payment-kit 1.19.12 → 1.19.13

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 CHANGED
@@ -14,7 +14,7 @@ repository:
14
14
  type: git
15
15
  url: git+https://github.com/blocklet/payment-kit.git
16
16
  specVersion: 1.2.8
17
- version: 1.19.12
17
+ version: 1.19.13
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.19.12",
3
+ "version": "1.19.13",
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,18 +46,18 @@
46
46
  "@abtnode/cron": "^1.16.46",
47
47
  "@arcblock/did": "^1.21.1",
48
48
  "@arcblock/did-auth-storage-nedb": "^1.7.1",
49
- "@arcblock/did-connect": "^3.0.39",
49
+ "@arcblock/did-connect": "^3.0.41",
50
50
  "@arcblock/did-util": "^1.21.1",
51
51
  "@arcblock/jwt": "^1.21.1",
52
- "@arcblock/ux": "^3.0.39",
52
+ "@arcblock/ux": "^3.0.41",
53
53
  "@arcblock/validator": "^1.21.1",
54
54
  "@blocklet/did-space-js": "^1.1.13",
55
55
  "@blocklet/error": "^0.2.5",
56
56
  "@blocklet/js-sdk": "^1.16.46",
57
57
  "@blocklet/logger": "^1.16.46",
58
- "@blocklet/payment-react": "1.19.12",
58
+ "@blocklet/payment-react": "1.19.13",
59
59
  "@blocklet/sdk": "^1.16.46",
60
- "@blocklet/ui-react": "^3.0.39",
60
+ "@blocklet/ui-react": "^3.0.41",
61
61
  "@blocklet/uploader": "^0.2.5",
62
62
  "@blocklet/xss": "^0.2.3",
63
63
  "@mui/icons-material": "^7.1.2",
@@ -124,7 +124,7 @@
124
124
  "devDependencies": {
125
125
  "@abtnode/types": "^1.16.46",
126
126
  "@arcblock/eslint-config-ts": "^0.3.3",
127
- "@blocklet/payment-types": "1.19.12",
127
+ "@blocklet/payment-types": "1.19.13",
128
128
  "@types/cookie-parser": "^1.4.9",
129
129
  "@types/cors": "^2.8.19",
130
130
  "@types/debug": "^4.1.12",
@@ -170,5 +170,5 @@
170
170
  "parser": "typescript"
171
171
  }
172
172
  },
173
- "gitHead": "2496138990f95bb979125127a06c5e9d731877c9"
173
+ "gitHead": "07c6878eb9d455f3898adfda7d07ca9e321e866c"
174
174
  }
@@ -63,7 +63,7 @@ export default function Chart({
63
63
  }}>
64
64
  <CartesianGrid strokeDasharray="3 3" stroke={theme.palette.grey[200]} />
65
65
  <Tooltip
66
- contentStyle={{ backgroundColor: theme.palette.background.paper, borderColor: theme.palette.grey[200] }}
66
+ contentStyle={{ backgroundColor: theme.palette.background.paper, borderColor: theme.palette.divider }}
67
67
  />
68
68
  {Object.keys(currencies).map((x: string, i) => {
69
69
  const dataKey = currencies[x]?.symbol as string;
@@ -15,6 +15,7 @@ interface ConditionalSectionProps {
15
15
  skeleton: boolean;
16
16
  children: ReactNode;
17
17
  skeletonComponent?: ReactNode;
18
+ onStateChange?: (state: 'hidden' | 'visible' | 'none') => void;
18
19
  }
19
20
 
20
21
  /**
@@ -29,10 +30,19 @@ interface ConditionalSectionProps {
29
30
  * 使用方式:
30
31
  * - 在任意深度的子组件中调用 useConditionalSection()?.hideRender()
31
32
  */
32
- export default function ConditionalSection({ skeleton, children, skeletonComponent = null }: ConditionalSectionProps) {
33
+ export default function ConditionalSection({
34
+ skeleton,
35
+ children,
36
+ skeletonComponent = null,
37
+ onStateChange = () => {},
38
+ }: ConditionalSectionProps) {
33
39
  const [renderState, setRenderState] = useState<'hidden' | 'visible' | 'none'>('hidden');
34
40
  const timerRef = useRef<NodeJS.Timeout | null>(null);
35
41
 
42
+ useEffect(() => {
43
+ onStateChange(renderState);
44
+ }, [renderState]);
45
+
36
46
  const handleHideRender = useCallback((hide: boolean = true) => {
37
47
  if (timerRef.current) {
38
48
  clearTimeout(timerRef.current);
@@ -99,6 +99,7 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
99
99
  borderColor: 'divider',
100
100
  boxShadow: 1,
101
101
  borderRadius: 1,
102
+ backgroundColor: 'background.default',
102
103
  }}>
103
104
  <CardContent sx={{ flexGrow: 1 }}>
104
105
  <Stack spacing={2}>
@@ -193,57 +194,59 @@ export default function CreditOverview({ customerId, settings, mode = 'portal' }
193
194
  <Tab label={t('admin.creditGrants.tab')} value={CreditTab.GRANTS} />
194
195
  <Tab label={t('admin.creditTransactions.tab')} value={CreditTab.TRANSACTIONS} />
195
196
  </Tabs>
196
- {/* 概览标签页 */}
197
- {creditTab === CreditTab.OVERVIEW && (
198
- <Box sx={{ width: '100%', mt: 1 }} key={creditTab}>
199
- <Box
200
- sx={{
201
- display: 'grid',
202
- gridTemplateColumns: {
203
- xs: 'repeat(1, 1fr)',
204
- md: 'repeat(2, 1fr)',
205
- },
206
- gap: 2,
207
- '@container (max-width: 600px)': {
208
- gridTemplateColumns: 'repeat(1, 1fr)',
209
- },
210
- }}>
211
- {filteredCreditCurrencies.map(renderCreditOverviewCard)}
212
- </Box>
213
-
214
- {filteredCreditCurrencies.length === 0 && (
197
+ <Box className="section-body">
198
+ {/* 概览标签页 */}
199
+ {creditTab === CreditTab.OVERVIEW && (
200
+ <Box sx={{ width: '100%', mt: 1 }} key={creditTab}>
215
201
  <Box
216
202
  sx={{
217
- display: 'flex',
218
- flexDirection: 'column',
219
- alignItems: 'center',
220
- justifyContent: 'center',
221
- py: 8,
222
- textAlign: 'center',
203
+ display: 'grid',
204
+ gridTemplateColumns: {
205
+ xs: 'repeat(1, 1fr)',
206
+ md: 'repeat(2, 1fr)',
207
+ },
208
+ gap: 2,
209
+ '@container (max-width: 600px)': {
210
+ gridTemplateColumns: 'repeat(1, 1fr)',
211
+ },
223
212
  }}>
224
- <Typography
225
- variant="h6"
226
- gutterBottom
227
- sx={{
228
- color: 'text.secondary',
229
- }}>
230
- {t('admin.customer.creditGrants.noGrants')}
231
- </Typography>
232
- <Typography
233
- variant="body2"
213
+ {filteredCreditCurrencies.map(renderCreditOverviewCard)}
214
+ </Box>
215
+
216
+ {filteredCreditCurrencies.length === 0 && (
217
+ <Box
234
218
  sx={{
235
- color: 'text.secondary',
219
+ display: 'flex',
220
+ flexDirection: 'column',
221
+ alignItems: 'center',
222
+ justifyContent: 'center',
223
+ py: 8,
224
+ textAlign: 'center',
236
225
  }}>
237
- {t('admin.customer.creditGrants.noGrantsDescription')}
238
- </Typography>
239
- </Box>
240
- )}
241
- </Box>
242
- )}
243
- {creditTab === CreditTab.GRANTS && <CreditGrantsList customer_id={customerId} mode={mode} key={creditTab} />}
244
- {creditTab === CreditTab.TRANSACTIONS && (
245
- <CreditTransactionsList customer_id={customerId} mode={mode} key={creditTab} />
246
- )}
226
+ <Typography
227
+ variant="h6"
228
+ gutterBottom
229
+ sx={{
230
+ color: 'text.secondary',
231
+ }}>
232
+ {t('admin.customer.creditGrants.noGrants')}
233
+ </Typography>
234
+ <Typography
235
+ variant="body2"
236
+ sx={{
237
+ color: 'text.secondary',
238
+ }}>
239
+ {t('admin.customer.creditGrants.noGrantsDescription')}
240
+ </Typography>
241
+ </Box>
242
+ )}
243
+ </Box>
244
+ )}
245
+ {creditTab === CreditTab.GRANTS && <CreditGrantsList customer_id={customerId} mode={mode} key={creditTab} />}
246
+ {creditTab === CreditTab.TRANSACTIONS && (
247
+ <CreditTransactionsList customer_id={customerId} mode={mode} key={creditTab} />
248
+ )}
249
+ </Box>
247
250
  </Stack>
248
251
  );
249
252
  }
@@ -72,7 +72,7 @@ export default function DrawerForm(rawProps: Props) {
72
72
  pt: 2,
73
73
  gap: 1,
74
74
  borderBottom: '1px solid',
75
- borderColor: 'grey.200',
75
+ borderColor: 'divider',
76
76
 
77
77
  '@media (max-width: 600px)': {
78
78
  '& > .addons-wrapper': {
@@ -522,7 +522,7 @@ const Root = styled(Box)`
522
522
  padding: 0;
523
523
  background: ${({ theme }) => theme.palette.background.paper};
524
524
  border: 1px solid;
525
- border-color: ${({ theme }) => theme.palette.grey[100]};
525
+ border-color: ${({ theme }) => theme.palette.divider};
526
526
  z-index: 999999;
527
527
  top: 15px;
528
528
  display: block;
@@ -100,7 +100,7 @@ export default function InfoCard(rawProps: Props) {
100
100
  color: 'background.paper',
101
101
  '&::before': {
102
102
  border: '1px solid',
103
- borderColor: 'grey.200',
103
+ borderColor: 'divider',
104
104
  backgroundColor: 'background.paper',
105
105
  },
106
106
  },
@@ -100,7 +100,7 @@ export function Download({ data }: { data: TInvoiceExpanded }) {
100
100
  size="small"
101
101
  onClick={generatePDF}
102
102
  disabled={!isReady || isGenerating}
103
- sx={{ borderColor: 'grey.100' }}>
103
+ sx={{ borderColor: 'divider' }}>
104
104
  {isGenerating ? (
105
105
  <Box sx={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
106
106
  <CircularProgress size={16} sx={{ color: 'inherit' }} />
@@ -34,10 +34,6 @@ const Root = styled(Dashboard)<{ padding: string }>`
34
34
  margin-bottom: 8px;
35
35
  }
36
36
 
37
- .MuiTabs-scroller {
38
- border-bottom: 1px solid ${({ theme }) => theme.palette.divider};
39
- }
40
-
41
37
  .page-content {
42
38
  margin-top: 2px;
43
39
  }
@@ -241,7 +241,7 @@ export default function MetadataForm({
241
241
  onClick={() => metadata.remove(index)}
242
242
  sx={{
243
243
  border: '1px solid',
244
- borderColor: 'grey.100',
244
+ borderColor: 'divider',
245
245
  borderRadius: 1,
246
246
  padding: '8px',
247
247
  }}>
@@ -418,10 +418,16 @@ export default function MeterEventsList({ meterId, paymentCurrency }: MeterEvent
418
418
  variant="outlined"
419
419
  startIcon={<CalendarTodayOutlined />}
420
420
  onClick={onTogglePicker}
421
+ size="large"
421
422
  sx={{
422
423
  minWidth: isMobile ? '100%' : 200,
423
424
  justifyContent: isMobile ? 'flex-start' : 'center',
424
425
  color: 'text.secondary',
426
+ borderColor: 'grey.300',
427
+ '&:hover': {
428
+ borderColor: 'primary.main',
429
+ },
430
+ backgroundColor: 'grey.50',
425
431
  }}>
426
432
  {dayjs(state.startDate).format('YYYY-MM-DD')} - {dayjs(state.endDate).format('YYYY-MM-DD')}
427
433
  </Button>
@@ -160,7 +160,7 @@ print("Event recorded:", response.json())`;
160
160
  const CodeBlock = styled(Paper)(({ theme }) => ({
161
161
  padding: theme.spacing(2),
162
162
  backgroundColor: theme.palette.grey[50],
163
- border: `1px solid ${theme.palette.grey[200]}`,
163
+ border: `1px solid ${theme.palette.divider}`,
164
164
  borderRadius: theme.shape.borderRadius,
165
165
  overflow: 'auto',
166
166
  '& pre': {
@@ -54,7 +54,7 @@ export default function LineItem({ prefix, product, valid, onUpdate, onRemove }:
54
54
  p: 2,
55
55
  borderWidth: valid ? 1 : 2,
56
56
  borderStyle: 'solid',
57
- borderColor: valid ? 'grey.100' : 'error.main',
57
+ borderColor: valid ? 'divider' : 'error.main',
58
58
  borderRadius: 2,
59
59
  position: 'relative',
60
60
  }}>
@@ -47,7 +47,7 @@ export default function ProductItem({ product, prices, valid, onUpdate, onRemove
47
47
  p: 2,
48
48
  borderWidth: valid ? 1 : 2,
49
49
  borderStyle: 'solid',
50
- borderColor: valid ? 'grey.100' : 'error.main',
50
+ borderColor: valid ? 'divider' : 'error.main',
51
51
  borderRadius: 2,
52
52
  position: 'relative',
53
53
  }}>
@@ -40,7 +40,7 @@ export default function MetadataForm() {
40
40
  onClick={() => features.remove(index)}
41
41
  sx={{
42
42
  border: '1px solid',
43
- borderColor: 'grey.100',
43
+ borderColor: 'divider',
44
44
  borderRadius: 1,
45
45
  padding: '8px',
46
46
  }}>
@@ -150,7 +150,7 @@ export default function Uploader({
150
150
 
151
151
  const Div = styled(Box)`
152
152
  border: 1px solid;
153
- border-color: ${({ theme }) => theme.palette.grey[100]};
153
+ border-color: ${({ theme }) => theme.palette.grey[300]};
154
154
  border-radius: 4px;
155
155
  cursor: pointer;
156
156
  width: 120px;
@@ -160,7 +160,7 @@ export default function WebhookAttempts({ event_id = '', webhook_endpoint_id = '
160
160
  md: 8,
161
161
  }}>
162
162
  {selected && (
163
- <Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid', borderColor: 'grey.100' }}>
163
+ <Stack direction="column" spacing={2} sx={{ pt: 3, pl: 3, borderLeft: '1px solid', borderColor: 'divider' }}>
164
164
  <Typography variant="h6">{event_id ? selected.endpoint.url : selected.event.type}</Typography>
165
165
  <Box>
166
166
  <Typography variant="h6">Response ({selected.response_status})</Typography>
@@ -63,7 +63,8 @@ export default flat({
63
63
  scope: 'Scope',
64
64
  effectiveDate: 'Effective Date',
65
65
  expirationDate: 'Expiration Date',
66
- creditGrant: 'Credit Grant',
66
+ creditGrant: 'Grant',
67
+ date: 'Date',
67
68
  subscription: 'Subscription',
68
69
  meterEvent: 'Meter Event',
69
70
  creditAmount: 'Credit',
@@ -63,6 +63,7 @@ export default flat({
63
63
  effectiveDate: '生效时间',
64
64
  expirationDate: '过期时间',
65
65
  creditGrant: '信用额度',
66
+ date: '日期',
66
67
  subscription: '订阅',
67
68
  meterEvent: '计量事件',
68
69
  creditAmount: '额度',
@@ -90,7 +90,7 @@ export default function WebhookDetail(props: { id: string }) {
90
90
  pt: 2,
91
91
  mt: 2,
92
92
  borderTop: '1px solid',
93
- borderColor: 'grey.100',
93
+ borderColor: 'divider',
94
94
  }}>
95
95
  <InfoMetric
96
96
  label={t('common.status')}
@@ -132,7 +132,7 @@ export default function CreatePricingTable() {
132
132
  flex: 2,
133
133
  position: 'relative',
134
134
  borderRight: '1px solid',
135
- borderColor: 'grey.100',
135
+ borderColor: 'divider',
136
136
  }}>
137
137
  <Stack
138
138
  spacing={2}
@@ -159,7 +159,7 @@ export default function CreatePricingTable() {
159
159
  justifyContent: 'flex-end',
160
160
  position: 'absolute',
161
161
  borderTop: '1px solid',
162
- borderColor: 'grey.100',
162
+ borderColor: 'divider',
163
163
  left: 0,
164
164
  bottom: 0,
165
165
  }}>
@@ -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', borderColor: 'grey.100' }}
29
+ sx={{ borderBottom: '1px solid', borderColor: 'divider' }}
30
30
  />
31
31
 
32
32
  <Stack
@@ -36,7 +36,7 @@ import type { SelectChangeEvent } from '@mui/material/Select';
36
36
  import { styled } from '@mui/system';
37
37
  import { useRequest, useSetState } from 'ahooks';
38
38
  import { flatten, isEmpty } from 'lodash';
39
- import { memo, useEffect, useState } from 'react';
39
+ import { memo, useEffect, useState, Fragment } from 'react';
40
40
  import { useNavigate, useSearchParams } from 'react-router-dom';
41
41
  import { joinURL } from 'ufo';
42
42
  import CreditOverview from '../../components/customer/credit-overview';
@@ -193,6 +193,10 @@ export default function CustomerHome() {
193
193
  const { t } = useLocaleContext();
194
194
  const { events } = useSessionContext();
195
195
  const { settings } = usePaymentContext();
196
+ const [domFilter, setDomFilter] = useSetState<any>({
197
+ credit: '',
198
+ revenue: '',
199
+ });
196
200
  const [subscriptionLoading, setSubscriptionLoading] = useState(false);
197
201
  const currencies = flatten(
198
202
  settings.paymentMethods?.map((method) =>
@@ -399,7 +403,7 @@ export default function CustomerHome() {
399
403
  p: 2,
400
404
  gap: 2,
401
405
  border: '1px solid',
402
- borderColor: 'grey.100',
406
+ borderColor: 'divider',
403
407
  boxShadow: 1,
404
408
  }}>
405
409
  <Stack
@@ -481,7 +485,7 @@ export default function CustomerHome() {
481
485
 
482
486
  // 独立的Credit Card组件
483
487
  const CreditCard = (
484
- <ConditionalSection skeleton={loadingCard}>
488
+ <ConditionalSection skeleton={loadingCard} onStateChange={(val) => setDomFilter({ credit: val })}>
485
489
  <Box className="base-card section section-credit">
486
490
  <Box className="section-header" sx={{ mb: 2 }}>
487
491
  <Typography variant="h3">{t('admin.creditGrants.title')}</Typography>
@@ -520,16 +524,28 @@ export default function CustomerHome() {
520
524
  );
521
525
 
522
526
  const RevenueCard = (
523
- <ConditionalSection skeleton={loadingCard}>
527
+ <ConditionalSection skeleton={loadingCard} onStateChange={(val) => setDomFilter({ revenue: val })}>
524
528
  <Box className="base-card section section-revenue">
525
529
  <Box className="section-header">
526
530
  <Typography variant="h3">{t('customer.payout.title')}</Typography>
527
531
  </Box>
528
- <CustomerRevenueList />
532
+ <Box className="section-body">
533
+ <CustomerRevenueList />
534
+ </Box>
529
535
  </Box>
530
536
  </ConditionalSection>
531
537
  );
532
538
 
539
+ const cards = [
540
+ { card: SummaryCard, key: 'summary' },
541
+ { card: CreditCard, key: 'credit' },
542
+ { card: SubscriptionCard, key: 'subscription' },
543
+ { card: InvoiceCard, key: 'invoice' },
544
+ { card: RevenueCard, key: 'revenue' },
545
+ ];
546
+
547
+ const visibleCards = cards.filter(({ card, key }) => card && domFilter[key] !== 'none');
548
+
533
549
  return (
534
550
  <Content>
535
551
  {data?.error && (
@@ -582,15 +598,12 @@ export default function CustomerHome() {
582
598
  />
583
599
  )}
584
600
  <Root>
585
- {SummaryCard}
586
- {SummaryCard && <Divider />}
587
- {CreditCard}
588
- {CreditCard && <Divider />}
589
- {SubscriptionCard}
590
- {SubscriptionCard && <Divider />}
591
- {InvoiceCard}
592
- {InvoiceCard && <Divider />}
593
- {RevenueCard}
601
+ {visibleCards.map(({ card, key }, index, array) => (
602
+ <Fragment key={key}>
603
+ {card}
604
+ {(domFilter[key] ? domFilter[key] === 'visible' : index < array.length - 1) && <Divider />}
605
+ </Fragment>
606
+ ))}
594
607
  </Root>
595
608
  </Content>
596
609
  );
@@ -627,6 +640,9 @@ const Root = styled(Stack)`
627
640
  gap: 24px;
628
641
  display: flex;
629
642
  flex-direction: column;
643
+ .section-body {
644
+ padding: 0 1px;
645
+ }
630
646
  @media (max-width: ${({ theme }) => theme.breakpoints.values.xl}px) {
631
647
  padding: 0px;
632
648
  .base-card {
@@ -170,7 +170,7 @@ export default function CustomerInvoiceDetail() {
170
170
  variant="outlined"
171
171
  color="primary"
172
172
  size="small"
173
- sx={{ borderColor: 'grey.100' }}
173
+ sx={{ borderColor: 'divider' }}
174
174
  disabled={state.paying}
175
175
  onClick={onPay}>
176
176
  {t('payment.customer.invoice.pay')}
@@ -25,7 +25,7 @@ function PreviewAvatars({ count }: { count: number }) {
25
25
  borderRadius: '50%',
26
26
  bgcolor: 'grey.200',
27
27
  border: '2px solid',
28
- borderColor: 'grey.100',
28
+ borderColor: 'divider',
29
29
  position: 'relative',
30
30
  marginLeft: i === 0 ? 0 : '-8px',
31
31
  zIndex: count - i,
@@ -151,7 +151,7 @@ export default function DonationPreview({ config }: { config: TSetting['settings
151
151
  borderRadius: '50%',
152
152
  bgcolor: 'grey.200',
153
153
  border: '2px solid',
154
- borderColor: 'grey.100',
154
+ borderColor: 'divider',
155
155
  position: 'relative',
156
156
  }}
157
157
  />
@@ -213,7 +213,7 @@ export default function DonationPreview({ config }: { config: TSetting['settings
213
213
  variant="outlined"
214
214
  size="small"
215
215
  sx={{
216
- borderColor: selectedAmount === amount ? 'primary.main' : 'grey.100',
216
+ borderColor: selectedAmount === amount ? 'primary.main' : 'divider',
217
217
  borderWidth: selectedAmount === amount ? 2 : 1,
218
218
  color: selectedAmount === amount ? 'primary.main' : 'text.primary',
219
219
  }}
@@ -226,7 +226,7 @@ export default function DonationPreview({ config }: { config: TSetting['settings
226
226
  variant="outlined"
227
227
  size="small"
228
228
  sx={{
229
- borderColor: showCustom ? 'primary.main' : 'grey.100',
229
+ borderColor: showCustom ? 'primary.main' : 'divider',
230
230
  borderWidth: showCustom ? 2 : 1,
231
231
  color: showCustom ? 'primary.main' : 'text.primary',
232
232
  }}