@blocklet/payment-react 1.19.0 → 1.19.1
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/es/components/blockchain/tx.d.ts +1 -1
- package/es/components/blockchain/tx.js +9 -11
- package/es/components/country-select.d.ts +1 -1
- package/es/components/date-range-picker.d.ts +13 -0
- package/es/components/date-range-picker.js +279 -0
- package/es/components/input.d.ts +5 -2
- package/es/components/input.js +6 -2
- package/es/components/label.d.ts +7 -0
- package/es/components/label.js +49 -0
- package/es/components/loading-button.d.ts +1 -1
- package/es/history/credit/grants-list.d.ts +14 -0
- package/es/history/credit/grants-list.js +215 -0
- package/es/history/credit/transactions-list.d.ts +13 -0
- package/es/history/credit/transactions-list.js +255 -0
- package/es/history/invoice/list.js +21 -1
- package/es/index.d.ts +5 -1
- package/es/index.js +10 -1
- package/es/libs/util.d.ts +2 -0
- package/es/libs/util.js +12 -0
- package/es/locales/en.js +20 -2
- package/es/locales/zh.js +20 -2
- package/es/payment/form/index.js +44 -6
- package/es/payment/index.js +18 -3
- package/es/payment/product-item.d.ts +8 -1
- package/es/payment/product-item.js +137 -5
- package/es/payment/summary.d.ts +3 -1
- package/es/payment/summary.js +9 -0
- package/lib/components/blockchain/tx.d.ts +1 -1
- package/lib/components/blockchain/tx.js +9 -8
- package/lib/components/country-select.d.ts +1 -1
- package/lib/components/date-range-picker.d.ts +13 -0
- package/lib/components/date-range-picker.js +329 -0
- package/lib/components/input.d.ts +5 -2
- package/lib/components/input.js +8 -4
- package/lib/components/label.d.ts +7 -0
- package/lib/components/label.js +60 -0
- package/lib/components/loading-button.d.ts +1 -1
- package/lib/history/credit/grants-list.d.ts +14 -0
- package/lib/history/credit/grants-list.js +277 -0
- package/lib/history/credit/transactions-list.d.ts +13 -0
- package/lib/history/credit/transactions-list.js +301 -0
- package/lib/history/invoice/list.js +24 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +39 -0
- package/lib/libs/util.d.ts +2 -0
- package/lib/libs/util.js +14 -0
- package/lib/locales/en.js +20 -2
- package/lib/locales/zh.js +20 -2
- package/lib/payment/form/index.js +45 -6
- package/lib/payment/index.js +20 -2
- package/lib/payment/product-item.d.ts +8 -1
- package/lib/payment/product-item.js +144 -4
- package/lib/payment/summary.d.ts +3 -1
- package/lib/payment/summary.js +9 -0
- package/package.json +3 -3
- package/src/components/blockchain/tx.tsx +9 -15
- package/src/components/country-select.tsx +2 -2
- package/src/components/date-range-picker.tsx +310 -0
- package/src/components/input.tsx +14 -3
- package/src/components/label.tsx +58 -0
- package/src/components/loading-button.tsx +1 -1
- package/src/history/credit/grants-list.tsx +276 -0
- package/src/history/credit/transactions-list.tsx +317 -0
- package/src/history/invoice/list.tsx +18 -1
- package/src/index.ts +9 -0
- package/src/libs/util.ts +14 -0
- package/src/locales/en.tsx +20 -0
- package/src/locales/zh.tsx +19 -0
- package/src/payment/form/address.tsx +2 -2
- package/src/payment/form/index.tsx +110 -52
- package/src/payment/index.tsx +17 -1
- package/src/payment/product-item.tsx +152 -4
- package/src/payment/summary.tsx +13 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
+
import { Box, Typography, Chip } from "@mui/material";
|
|
4
|
+
import { useRequest } from "ahooks";
|
|
5
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
6
|
+
import { useNavigate } from "react-router-dom";
|
|
7
|
+
import { styled } from "@mui/system";
|
|
8
|
+
import { formatBNStr, formatToDate } from "../../libs/util.js";
|
|
9
|
+
import { usePaymentContext } from "../../contexts/payment.js";
|
|
10
|
+
import api from "../../libs/api.js";
|
|
11
|
+
import Table from "../../components/table.js";
|
|
12
|
+
import { createLink, handleNavigation } from "../../libs/navigation.js";
|
|
13
|
+
const fetchData = (params = {}) => {
|
|
14
|
+
const search = new URLSearchParams();
|
|
15
|
+
Object.keys(params).forEach((key) => {
|
|
16
|
+
if (params[key]) {
|
|
17
|
+
search.set(key, String(params[key]));
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return api.get(`/api/credit-grants?${search.toString()}`).then((res) => res.data);
|
|
21
|
+
};
|
|
22
|
+
export function StatusChip({ status, label }) {
|
|
23
|
+
const getStatusColor = (statusValue) => {
|
|
24
|
+
switch (statusValue) {
|
|
25
|
+
case "granted":
|
|
26
|
+
return "success";
|
|
27
|
+
case "pending":
|
|
28
|
+
return "warning";
|
|
29
|
+
case "expired":
|
|
30
|
+
return "default";
|
|
31
|
+
case "depleted":
|
|
32
|
+
return "default";
|
|
33
|
+
case "voided":
|
|
34
|
+
return "default";
|
|
35
|
+
default:
|
|
36
|
+
return "default";
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return /* @__PURE__ */ jsx(Chip, { label: label || status, size: "small", color: getStatusColor(status) });
|
|
40
|
+
}
|
|
41
|
+
const getLink = (grant, inDashboard) => {
|
|
42
|
+
let path = `/customer/credit-grant/${grant.id}`;
|
|
43
|
+
if (inDashboard) {
|
|
44
|
+
path = `/admin/customers/${grant.id}`;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
link: createLink(path),
|
|
48
|
+
connect: false
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const GrantsTable = React.memo((props) => {
|
|
52
|
+
const { pageSize, status = "", customer_id, subscription_id, onTableDataChange } = props;
|
|
53
|
+
const listKey = "credit-grants-table";
|
|
54
|
+
const { t, locale } = useLocaleContext();
|
|
55
|
+
const { session } = usePaymentContext();
|
|
56
|
+
const navigate = useNavigate();
|
|
57
|
+
const isAdmin = ["owner", "admin"].includes(session?.user?.role || "");
|
|
58
|
+
const inDashboard = props.mode === "dashboard" && isAdmin;
|
|
59
|
+
const effectiveCustomerId = customer_id || session?.user?.did;
|
|
60
|
+
const [search, setSearch] = useState({
|
|
61
|
+
pageSize: pageSize || 10,
|
|
62
|
+
page: 1
|
|
63
|
+
});
|
|
64
|
+
const { loading, data = { list: [], count: 0 } } = useRequest(
|
|
65
|
+
() => fetchData({
|
|
66
|
+
...search,
|
|
67
|
+
status,
|
|
68
|
+
customer_id: effectiveCustomerId,
|
|
69
|
+
subscription_id
|
|
70
|
+
}),
|
|
71
|
+
{
|
|
72
|
+
refreshDeps: [search, status, effectiveCustomerId, subscription_id]
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
const prevData = useRef(data);
|
|
76
|
+
const handleLinkClick = (e, grant) => {
|
|
77
|
+
const { link } = getLink(grant, inDashboard);
|
|
78
|
+
handleNavigation(e, link, navigate, { target: link.external ? "_blank" : "_self" });
|
|
79
|
+
};
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
if (onTableDataChange) {
|
|
82
|
+
onTableDataChange(data, prevData.current);
|
|
83
|
+
prevData.current = data;
|
|
84
|
+
}
|
|
85
|
+
}, [data]);
|
|
86
|
+
const columns = [
|
|
87
|
+
{
|
|
88
|
+
label: t("common.name"),
|
|
89
|
+
name: "name",
|
|
90
|
+
options: {
|
|
91
|
+
customBodyRenderLite: (_, index) => {
|
|
92
|
+
const grant = data?.list[index];
|
|
93
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: grant.name || grant.id });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: t("common.status"),
|
|
99
|
+
name: "status",
|
|
100
|
+
options: {
|
|
101
|
+
customBodyRenderLite: (_, index) => {
|
|
102
|
+
const grant = data?.list[index];
|
|
103
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: /* @__PURE__ */ jsx(StatusChip, { status: grant.status, label: t(`admin.customer.creditGrants.status.${grant.status}`) }) });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
label: t("common.remainingCredit"),
|
|
109
|
+
name: "remaining_amount",
|
|
110
|
+
align: "right",
|
|
111
|
+
options: {
|
|
112
|
+
customBodyRenderLite: (_, index) => {
|
|
113
|
+
const grant = data?.list[index];
|
|
114
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
|
|
115
|
+
formatBNStr(grant.remaining_amount, grant.paymentCurrency.decimal),
|
|
116
|
+
" ",
|
|
117
|
+
grant.paymentCurrency.symbol
|
|
118
|
+
] }) });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
label: t("common.scope"),
|
|
124
|
+
name: "scope",
|
|
125
|
+
options: {
|
|
126
|
+
customBodyRenderLite: (_, index) => {
|
|
127
|
+
const grant = data?.list[index];
|
|
128
|
+
let scope = "general";
|
|
129
|
+
if (grant.applicability_config?.scope?.prices) {
|
|
130
|
+
scope = "specific";
|
|
131
|
+
}
|
|
132
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: scope === "specific" ? t("common.specific") : t("common.general") });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
label: t("common.effectiveDate"),
|
|
138
|
+
name: "effective_at",
|
|
139
|
+
options: {
|
|
140
|
+
customBodyRenderLite: (_, index) => {
|
|
141
|
+
const grant = data?.list[index];
|
|
142
|
+
const effectiveAt = grant.effective_at ? grant.effective_at * 1e3 : grant.created_at;
|
|
143
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: formatToDate(effectiveAt, locale, "YYYY-MM-DD HH:mm") });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: t("common.expirationDate"),
|
|
149
|
+
name: "expires_at",
|
|
150
|
+
options: {
|
|
151
|
+
customBodyRenderLite: (_, index) => {
|
|
152
|
+
const grant = data?.list[index];
|
|
153
|
+
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: /* @__PURE__ */ jsx(Typography, { variant: "body2", children: grant.expires_at ? formatToDate(grant.expires_at * 1e3, locale, "YYYY-MM-DD HH:mm") : "-" }) });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
];
|
|
158
|
+
const onTableChange = ({ page, rowsPerPage }) => {
|
|
159
|
+
if (search.pageSize !== rowsPerPage) {
|
|
160
|
+
setSearch((x) => ({ ...x, pageSize: rowsPerPage, page: 1 }));
|
|
161
|
+
} else if (search.page !== page + 1) {
|
|
162
|
+
setSearch((x) => ({ ...x, page: page + 1 }));
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
return /* @__PURE__ */ jsx(TableRoot, { children: /* @__PURE__ */ jsx(
|
|
166
|
+
Table,
|
|
167
|
+
{
|
|
168
|
+
hasRowLink: true,
|
|
169
|
+
durable: `__${listKey}__`,
|
|
170
|
+
durableKeys: ["page", "rowsPerPage", "searchText"],
|
|
171
|
+
data: data.list,
|
|
172
|
+
columns,
|
|
173
|
+
options: {
|
|
174
|
+
count: data.count,
|
|
175
|
+
page: search.page - 1,
|
|
176
|
+
rowsPerPage: search.pageSize
|
|
177
|
+
},
|
|
178
|
+
loading,
|
|
179
|
+
onChange: onTableChange,
|
|
180
|
+
toolbar: false,
|
|
181
|
+
sx: { mt: 2 },
|
|
182
|
+
showMobile: false,
|
|
183
|
+
mobileTDFlexDirection: "row",
|
|
184
|
+
emptyNodeText: t("admin.creditGrants.noGrants")
|
|
185
|
+
}
|
|
186
|
+
) });
|
|
187
|
+
});
|
|
188
|
+
const TableRoot = styled(Box)`
|
|
189
|
+
@media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
|
|
190
|
+
.MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > td.MuiTableCell-root {
|
|
191
|
+
> div {
|
|
192
|
+
width: fit-content;
|
|
193
|
+
flex: inherit;
|
|
194
|
+
font-size: 14px;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
.invoice-summary {
|
|
198
|
+
padding-right: 20px;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
export default function CreditGrantsList(rawProps) {
|
|
203
|
+
const props = Object.assign(
|
|
204
|
+
{
|
|
205
|
+
customer_id: "",
|
|
206
|
+
subscription_id: "",
|
|
207
|
+
status: "granted,pending,depleted,expired",
|
|
208
|
+
pageSize: 10,
|
|
209
|
+
onTableDataChange: () => {
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
rawProps
|
|
213
|
+
);
|
|
214
|
+
return /* @__PURE__ */ jsx(GrantsTable, { ...props });
|
|
215
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
customer_id?: string;
|
|
3
|
+
subscription_id?: string;
|
|
4
|
+
credit_grant_id?: string;
|
|
5
|
+
pageSize?: number;
|
|
6
|
+
onTableDataChange?: Function;
|
|
7
|
+
showAdminColumns?: boolean;
|
|
8
|
+
showTimeFilter?: boolean;
|
|
9
|
+
source?: string;
|
|
10
|
+
mode?: 'dashboard' | 'portal';
|
|
11
|
+
};
|
|
12
|
+
export default function CreditTransactionsList(rawProps: Props): JSX.Element;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
+
import { Box, Typography, Stack, Link, Grid } from "@mui/material";
|
|
4
|
+
import { useRequest } from "ahooks";
|
|
5
|
+
import { useNavigate } from "react-router-dom";
|
|
6
|
+
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
+
import { joinURL } from "ufo";
|
|
8
|
+
import { styled } from "@mui/system";
|
|
9
|
+
import DateRangePicker from "../../components/date-range-picker.js";
|
|
10
|
+
import { formatBNStr, formatToDate, getPrefix } from "../../libs/util.js";
|
|
11
|
+
import { usePaymentContext } from "../../contexts/payment.js";
|
|
12
|
+
import api from "../../libs/api.js";
|
|
13
|
+
import Table from "../../components/table.js";
|
|
14
|
+
import { createLink, handleNavigation } from "../../libs/navigation.js";
|
|
15
|
+
const fetchData = (params = {}) => {
|
|
16
|
+
const search = new URLSearchParams();
|
|
17
|
+
Object.keys(params).forEach((key) => {
|
|
18
|
+
if (params[key]) {
|
|
19
|
+
search.set(key, String(params[key]));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
return api.get(`/api/credit-transactions?${search.toString()}`).then((res) => res.data);
|
|
23
|
+
};
|
|
24
|
+
const getGrantDetailLink = (grantId, inDashboard) => {
|
|
25
|
+
let path = `/customer/credit-grant/${grantId}`;
|
|
26
|
+
if (inDashboard) {
|
|
27
|
+
path = `/admin/customers/${grantId}`;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
link: createLink(path),
|
|
31
|
+
connect: false
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
const TransactionsTable = React.memo((props) => {
|
|
35
|
+
const {
|
|
36
|
+
pageSize,
|
|
37
|
+
customer_id,
|
|
38
|
+
subscription_id,
|
|
39
|
+
credit_grant_id,
|
|
40
|
+
onTableDataChange,
|
|
41
|
+
showAdminColumns = false,
|
|
42
|
+
showTimeFilter = false,
|
|
43
|
+
source,
|
|
44
|
+
mode = "portal"
|
|
45
|
+
} = props;
|
|
46
|
+
const listKey = "credit-transactions-table";
|
|
47
|
+
const { t, locale } = useLocaleContext();
|
|
48
|
+
const { session } = usePaymentContext();
|
|
49
|
+
const isAdmin = ["owner", "admin"].includes(session?.user?.role || "");
|
|
50
|
+
const navigate = useNavigate();
|
|
51
|
+
const effectiveCustomerId = customer_id || session?.user?.did;
|
|
52
|
+
const [search, setSearch] = useState({
|
|
53
|
+
pageSize: pageSize || 10,
|
|
54
|
+
page: 1
|
|
55
|
+
});
|
|
56
|
+
const [filters, setFilters] = useState({
|
|
57
|
+
start: void 0,
|
|
58
|
+
end: void 0
|
|
59
|
+
});
|
|
60
|
+
const handleDateRangeChange = useCallback((newValue) => {
|
|
61
|
+
setFilters(newValue);
|
|
62
|
+
setSearch((prev) => ({
|
|
63
|
+
...prev,
|
|
64
|
+
page: 1,
|
|
65
|
+
start: newValue.start || void 0,
|
|
66
|
+
end: newValue.end || void 0
|
|
67
|
+
}));
|
|
68
|
+
}, []);
|
|
69
|
+
const { loading, data = { list: [], count: 0 } } = useRequest(
|
|
70
|
+
() => fetchData({
|
|
71
|
+
...search,
|
|
72
|
+
customer_id: effectiveCustomerId,
|
|
73
|
+
subscription_id,
|
|
74
|
+
credit_grant_id,
|
|
75
|
+
source
|
|
76
|
+
}),
|
|
77
|
+
{
|
|
78
|
+
refreshDeps: [search, effectiveCustomerId, subscription_id, credit_grant_id, source]
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (showTimeFilter && !search.start && !search.end) {
|
|
83
|
+
handleDateRangeChange(filters);
|
|
84
|
+
}
|
|
85
|
+
}, [showTimeFilter, handleDateRangeChange, search.start, search.end, filters]);
|
|
86
|
+
const prevData = useRef(data);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (onTableDataChange) {
|
|
89
|
+
onTableDataChange(data, prevData.current);
|
|
90
|
+
prevData.current = data;
|
|
91
|
+
}
|
|
92
|
+
}, [data]);
|
|
93
|
+
const columns = [
|
|
94
|
+
{
|
|
95
|
+
label: t("common.creditAmount"),
|
|
96
|
+
name: "credit_amount",
|
|
97
|
+
align: "right",
|
|
98
|
+
width: 120,
|
|
99
|
+
options: {
|
|
100
|
+
customBodyRenderLite: (_, index) => {
|
|
101
|
+
const transaction = data?.list[index];
|
|
102
|
+
const unit = transaction.meter?.unit || transaction.paymentCurrency.symbol;
|
|
103
|
+
return /* @__PURE__ */ jsxs(Typography, { children: [
|
|
104
|
+
formatBNStr(transaction.credit_amount, transaction.paymentCurrency.decimal),
|
|
105
|
+
" ",
|
|
106
|
+
unit
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
!credit_grant_id && {
|
|
112
|
+
label: t("common.creditGrant"),
|
|
113
|
+
name: "credit_grant",
|
|
114
|
+
options: {
|
|
115
|
+
customBodyRenderLite: (_, index) => {
|
|
116
|
+
const transaction = data?.list[index];
|
|
117
|
+
return /* @__PURE__ */ jsx(
|
|
118
|
+
Stack,
|
|
119
|
+
{
|
|
120
|
+
direction: "row",
|
|
121
|
+
spacing: 1,
|
|
122
|
+
onClick: (e) => {
|
|
123
|
+
const link = getGrantDetailLink(transaction.credit_grant_id, isAdmin && mode === "dashboard");
|
|
124
|
+
handleNavigation(e, link.link, navigate);
|
|
125
|
+
},
|
|
126
|
+
sx: {
|
|
127
|
+
alignItems: "center"
|
|
128
|
+
},
|
|
129
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.link", cursor: "pointer" }, children: transaction.creditGrant.name || `Grant ${transaction.credit_grant_id.slice(-6)}` })
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: t("common.description"),
|
|
137
|
+
name: "subscription",
|
|
138
|
+
options: {
|
|
139
|
+
customBodyRenderLite: (_, index) => {
|
|
140
|
+
const transaction = data?.list[index];
|
|
141
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", children: transaction.subscription?.description || transaction.description });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
...showAdminColumns && isAdmin ? [
|
|
146
|
+
{
|
|
147
|
+
label: t("common.meterEvent"),
|
|
148
|
+
name: "meter_event",
|
|
149
|
+
options: {
|
|
150
|
+
customBodyRenderLite: (_, index) => {
|
|
151
|
+
const transaction = data?.list[index];
|
|
152
|
+
if (!transaction.meter) {
|
|
153
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", children: "-" });
|
|
154
|
+
}
|
|
155
|
+
return /* @__PURE__ */ jsx(Link, { href: joinURL(getPrefix(), `/admin/billing/${transaction.meter.id}`), children: /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.link" }, children: transaction.meter.event_name }) });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
] : [],
|
|
160
|
+
{
|
|
161
|
+
label: t("admin.creditTransactions.transactionDate"),
|
|
162
|
+
name: "created_at",
|
|
163
|
+
options: {
|
|
164
|
+
customBodyRenderLite: (_, index) => {
|
|
165
|
+
const transaction = data?.list[index];
|
|
166
|
+
return /* @__PURE__ */ jsx(Typography, { variant: "body2", children: formatToDate(transaction.created_at, locale, "YYYY-MM-DD HH:mm:ss") });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
].filter(Boolean);
|
|
171
|
+
const onTableChange = ({ page, rowsPerPage }) => {
|
|
172
|
+
if (search.pageSize !== rowsPerPage) {
|
|
173
|
+
setSearch((x) => ({ ...x, pageSize: rowsPerPage, page: 1 }));
|
|
174
|
+
} else if (search.page !== page + 1) {
|
|
175
|
+
setSearch((x) => ({ ...x, page: page + 1 }));
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
return /* @__PURE__ */ jsxs(TableRoot, { children: [
|
|
179
|
+
showTimeFilter && /* @__PURE__ */ jsx(Box, { sx: { my: 2 }, children: /* @__PURE__ */ jsx(Box, { sx: { mt: 2 }, children: /* @__PURE__ */ jsx(
|
|
180
|
+
Grid,
|
|
181
|
+
{
|
|
182
|
+
container: true,
|
|
183
|
+
spacing: 2,
|
|
184
|
+
sx: {
|
|
185
|
+
alignItems: "center"
|
|
186
|
+
},
|
|
187
|
+
children: /* @__PURE__ */ jsx(
|
|
188
|
+
Grid,
|
|
189
|
+
{
|
|
190
|
+
size: {
|
|
191
|
+
xs: 12,
|
|
192
|
+
sm: 6,
|
|
193
|
+
md: 4
|
|
194
|
+
},
|
|
195
|
+
children: /* @__PURE__ */ jsx(DateRangePicker, { value: filters, onChange: handleDateRangeChange, size: "small", fullWidth: true })
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
) }) }),
|
|
200
|
+
/* @__PURE__ */ jsx(
|
|
201
|
+
Table,
|
|
202
|
+
{
|
|
203
|
+
hasRowLink: true,
|
|
204
|
+
durable: `__${listKey}__`,
|
|
205
|
+
durableKeys: ["page", "rowsPerPage"],
|
|
206
|
+
data: data.list,
|
|
207
|
+
columns,
|
|
208
|
+
options: {
|
|
209
|
+
count: data.count,
|
|
210
|
+
page: search.page - 1,
|
|
211
|
+
rowsPerPage: search.pageSize
|
|
212
|
+
},
|
|
213
|
+
loading,
|
|
214
|
+
onChange: onTableChange,
|
|
215
|
+
toolbar: false,
|
|
216
|
+
sx: { mt: 2 },
|
|
217
|
+
showMobile: false,
|
|
218
|
+
mobileTDFlexDirection: "row",
|
|
219
|
+
emptyNodeText: t("admin.creditTransactions.noTransactions")
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
] });
|
|
223
|
+
});
|
|
224
|
+
const TableRoot = styled(Box)`
|
|
225
|
+
@media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
|
|
226
|
+
.MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > td.MuiTableCell-root {
|
|
227
|
+
> div {
|
|
228
|
+
width: fit-content;
|
|
229
|
+
flex: inherit;
|
|
230
|
+
font-size: 14px;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
.invoice-summary {
|
|
234
|
+
padding-right: 20px;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
`;
|
|
238
|
+
export default function CreditTransactionsList(rawProps) {
|
|
239
|
+
const props = Object.assign(
|
|
240
|
+
{
|
|
241
|
+
customer_id: "",
|
|
242
|
+
subscription_id: "",
|
|
243
|
+
credit_grant_id: "",
|
|
244
|
+
source: "",
|
|
245
|
+
pageSize: 10,
|
|
246
|
+
onTableDataChange: () => {
|
|
247
|
+
},
|
|
248
|
+
showAdminColumns: false,
|
|
249
|
+
showTimeFilter: false,
|
|
250
|
+
mode: "portal"
|
|
251
|
+
},
|
|
252
|
+
rawProps
|
|
253
|
+
);
|
|
254
|
+
return /* @__PURE__ */ jsx(TransactionsTable, { ...props });
|
|
255
|
+
}
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
3
3
|
import Toast from "@arcblock/ux/lib/Toast";
|
|
4
4
|
import { OpenInNewOutlined } from "@mui/icons-material";
|
|
5
|
-
import { Box, Button, CircularProgress, Stack, Typography, Tooltip } from "@mui/material";
|
|
5
|
+
import { Box, Button, CircularProgress, Stack, Typography, Tooltip, Avatar } from "@mui/material";
|
|
6
6
|
import { styled } from "@mui/system";
|
|
7
7
|
import { useInfiniteScroll, useRequest, useSetState } from "ahooks";
|
|
8
8
|
import React, { useEffect, useRef, useState } from "react";
|
|
@@ -160,6 +160,26 @@ const InvoiceTable = React.memo((props) => {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
},
|
|
163
|
+
{
|
|
164
|
+
label: t("common.paymentMethod"),
|
|
165
|
+
name: "paymentMethod",
|
|
166
|
+
options: {
|
|
167
|
+
customBodyRenderLite: (_, index) => {
|
|
168
|
+
const invoice = data?.list[index];
|
|
169
|
+
return /* @__PURE__ */ jsxs(
|
|
170
|
+
Typography,
|
|
171
|
+
{
|
|
172
|
+
sx: { display: "flex", alignItems: "center", whiteSpace: "nowrap" },
|
|
173
|
+
onClick: (e) => handleLinkClick(e, invoice),
|
|
174
|
+
children: [
|
|
175
|
+
/* @__PURE__ */ jsx(Avatar, { src: invoice.paymentMethod.logo, sx: { width: 18, height: 18, mr: 1 } }),
|
|
176
|
+
invoice.paymentMethod.name
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
163
183
|
{
|
|
164
184
|
label: t("common.type"),
|
|
165
185
|
name: "billing_reason",
|
package/es/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import TxGas from './components/blockchain/gas';
|
|
|
5
5
|
import TxLink from './components/blockchain/tx';
|
|
6
6
|
import ConfirmDialog from './components/confirm';
|
|
7
7
|
import FormInput from './components/input';
|
|
8
|
+
import FormLabel from './components/label';
|
|
8
9
|
import Livemode from './components/livemode';
|
|
9
10
|
import PricingTable from './components/pricing-table';
|
|
10
11
|
import Table from './components/table';
|
|
@@ -13,6 +14,8 @@ import Status from './components/status';
|
|
|
13
14
|
import Switch from './components/switch-button';
|
|
14
15
|
import CustomerInvoiceList from './history/invoice/list';
|
|
15
16
|
import CustomerPaymentList from './history/payment/list';
|
|
17
|
+
import CreditGrantsList, { StatusChip as CreditStatusChip } from './history/credit/grants-list';
|
|
18
|
+
import CreditTransactionsList from './history/credit/transactions-list';
|
|
16
19
|
import api from './libs/api';
|
|
17
20
|
import dayjs from './libs/dayjs';
|
|
18
21
|
import Amount from './payment/amount';
|
|
@@ -32,6 +35,7 @@ import OverdueInvoicePayment from './components/over-due-invoice-payment';
|
|
|
32
35
|
import PaymentBeneficiaries from './components/payment-beneficiaries';
|
|
33
36
|
import LoadingButton from './components/loading-button';
|
|
34
37
|
import ResumeSubscription from './components/resume-subscription';
|
|
38
|
+
import DateRangePicker from './components/date-range-picker';
|
|
35
39
|
export { PaymentThemeProvider } from './theme';
|
|
36
40
|
export * from './libs/util';
|
|
37
41
|
export * from './libs/connect';
|
|
@@ -46,4 +50,4 @@ export * from './hooks/scroll';
|
|
|
46
50
|
export * from './hooks/keyboard';
|
|
47
51
|
export * from './libs/validator';
|
|
48
52
|
export { translations, createTranslator } from './locales';
|
|
49
|
-
export { createLazyComponent, api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, Link, OverdueInvoicePayment, PaymentBeneficiaries, LoadingButton, DonateDetails, ResumeSubscription, };
|
|
53
|
+
export { createLazyComponent, api, dayjs, FormInput, FormLabel, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, Link, OverdueInvoicePayment, PaymentBeneficiaries, LoadingButton, DonateDetails, ResumeSubscription, CreditGrantsList, CreditTransactionsList, DateRangePicker, CreditStatusChip, };
|
package/es/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import TxGas from "./components/blockchain/gas.js";
|
|
|
5
5
|
import TxLink from "./components/blockchain/tx.js";
|
|
6
6
|
import ConfirmDialog from "./components/confirm.js";
|
|
7
7
|
import FormInput from "./components/input.js";
|
|
8
|
+
import FormLabel from "./components/label.js";
|
|
8
9
|
import Livemode from "./components/livemode.js";
|
|
9
10
|
import PricingTable from "./components/pricing-table.js";
|
|
10
11
|
import Table from "./components/table.js";
|
|
@@ -13,6 +14,8 @@ import Status from "./components/status.js";
|
|
|
13
14
|
import Switch from "./components/switch-button.js";
|
|
14
15
|
import CustomerInvoiceList from "./history/invoice/list.js";
|
|
15
16
|
import CustomerPaymentList from "./history/payment/list.js";
|
|
17
|
+
import CreditGrantsList, { StatusChip as CreditStatusChip } from "./history/credit/grants-list.js";
|
|
18
|
+
import CreditTransactionsList from "./history/credit/transactions-list.js";
|
|
16
19
|
import api from "./libs/api.js";
|
|
17
20
|
import dayjs from "./libs/dayjs.js";
|
|
18
21
|
import Amount from "./payment/amount.js";
|
|
@@ -32,6 +35,7 @@ import OverdueInvoicePayment from "./components/over-due-invoice-payment.js";
|
|
|
32
35
|
import PaymentBeneficiaries from "./components/payment-beneficiaries.js";
|
|
33
36
|
import LoadingButton from "./components/loading-button.js";
|
|
34
37
|
import ResumeSubscription from "./components/resume-subscription.js";
|
|
38
|
+
import DateRangePicker from "./components/date-range-picker.js";
|
|
35
39
|
export { PaymentThemeProvider } from "./theme/index.js";
|
|
36
40
|
export * from "./libs/util.js";
|
|
37
41
|
export * from "./libs/connect.js";
|
|
@@ -51,6 +55,7 @@ export {
|
|
|
51
55
|
api,
|
|
52
56
|
dayjs,
|
|
53
57
|
FormInput,
|
|
58
|
+
FormLabel,
|
|
54
59
|
PhoneInput,
|
|
55
60
|
AddressForm,
|
|
56
61
|
StripeForm,
|
|
@@ -81,5 +86,9 @@ export {
|
|
|
81
86
|
PaymentBeneficiaries,
|
|
82
87
|
LoadingButton,
|
|
83
88
|
DonateDetails,
|
|
84
|
-
ResumeSubscription
|
|
89
|
+
ResumeSubscription,
|
|
90
|
+
CreditGrantsList,
|
|
91
|
+
CreditTransactionsList,
|
|
92
|
+
DateRangePicker,
|
|
93
|
+
CreditStatusChip
|
|
85
94
|
};
|
package/es/libs/util.d.ts
CHANGED
|
@@ -129,3 +129,5 @@ export declare function parseMarkedText(text: string): Array<{
|
|
|
129
129
|
content: string;
|
|
130
130
|
}>;
|
|
131
131
|
export declare function getTokenBalanceLink(method: TPaymentMethod, address: string): string;
|
|
132
|
+
export declare function isCreditMetered(price: TPrice): boolean;
|
|
133
|
+
export declare function showStaking(method: TPaymentMethod, currency: TPaymentCurrency, noStake: boolean): boolean;
|
package/es/libs/util.js
CHANGED
|
@@ -1001,3 +1001,15 @@ export function getTokenBalanceLink(method, address) {
|
|
|
1001
1001
|
}
|
|
1002
1002
|
return "";
|
|
1003
1003
|
}
|
|
1004
|
+
export function isCreditMetered(price) {
|
|
1005
|
+
return !!(price.type === "recurring" && price.recurring?.usage_type === "metered" && price.recurring?.meter_id);
|
|
1006
|
+
}
|
|
1007
|
+
export function showStaking(method, currency, noStake) {
|
|
1008
|
+
if (noStake) {
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
if (method.type === "arcblock") {
|
|
1012
|
+
return currency.type !== "credit";
|
|
1013
|
+
}
|
|
1014
|
+
return true;
|
|
1015
|
+
}
|
package/es/locales/en.js
CHANGED
|
@@ -28,6 +28,10 @@ export default flat({
|
|
|
28
28
|
remove: "Remove",
|
|
29
29
|
removed: "Resource removed",
|
|
30
30
|
confirm: "Confirm",
|
|
31
|
+
clear: "Clear",
|
|
32
|
+
selectTimeRange: "Select time range",
|
|
33
|
+
startDate: "Start date",
|
|
34
|
+
endDate: "End date",
|
|
31
35
|
upload: "Upload",
|
|
32
36
|
change: "Change",
|
|
33
37
|
cancel: "Cancel",
|
|
@@ -100,7 +104,8 @@ export default flat({
|
|
|
100
104
|
scan: "Use following methods to complete this {action}",
|
|
101
105
|
confirm: "Confirm",
|
|
102
106
|
cancel: "Cancel"
|
|
103
|
-
}
|
|
107
|
+
},
|
|
108
|
+
paymentMethod: "Payment Method"
|
|
104
109
|
},
|
|
105
110
|
payment: {
|
|
106
111
|
checkout: {
|
|
@@ -204,6 +209,11 @@ export default flat({
|
|
|
204
209
|
add: "Add to order",
|
|
205
210
|
remove: "Remove from order"
|
|
206
211
|
},
|
|
212
|
+
credit: {
|
|
213
|
+
oneTimeInfo: "You will receive {amount} {symbol} credits after payment",
|
|
214
|
+
recurringInfo: "You will receive {amount} {symbol} credits {period}",
|
|
215
|
+
expiresIn: "credits have a validity period of {duration} {unit}"
|
|
216
|
+
},
|
|
207
217
|
expired: {
|
|
208
218
|
title: "Expired Link",
|
|
209
219
|
description: "This link has expired. This means that your payment has already been processed or your session has expired."
|
|
@@ -232,7 +242,15 @@ export default flat({
|
|
|
232
242
|
payer: "Account",
|
|
233
243
|
amount: "Amount",
|
|
234
244
|
failed: "Account changed, please pay manually.",
|
|
235
|
-
balanceLink: "View Balance"
|
|
245
|
+
balanceLink: "View Balance",
|
|
246
|
+
credit: {
|
|
247
|
+
title: "Confirm Credit Payment",
|
|
248
|
+
availableAmount: "Available Credit: {amount}",
|
|
249
|
+
confirmMessage: "You will use {amount} credits to subscribe to this service.",
|
|
250
|
+
meteringSubscriptionMessage: "This subscription service will deduct credits in real-time based on actual usage. You currently have {available} credits available. Confirm to continue?",
|
|
251
|
+
insufficientTitle: "Insufficient Credit",
|
|
252
|
+
insufficientMessage: "This subscription service will deduct credits in real-time based on actual usage. You currently have insufficient credits. Please top up your credits first."
|
|
253
|
+
}
|
|
236
254
|
}
|
|
237
255
|
},
|
|
238
256
|
customer: {
|