@blocklet/payment-react
Version:
Reusable react components for payment kit v2
216 lines (215 loc) • 7.16 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
import { Box, Typography, Chip } from "@mui/material";
import { useRequest } from "ahooks";
import React, { useEffect, useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import { styled } from "@mui/system";
import { formatBNStr, formatToDate } from "../../libs/util.js";
import { usePaymentContext } from "../../contexts/payment.js";
import api from "../../libs/api.js";
import Table from "../../components/table.js";
import { createLink, handleNavigation } from "../../libs/navigation.js";
const fetchData = (params = {}) => {
const search = new URLSearchParams();
Object.keys(params).forEach((key) => {
if (params[key]) {
search.set(key, String(params[key]));
}
});
return api.get(`/api/credit-grants?${search.toString()}`).then((res) => res.data);
};
export function StatusChip({ status, label }) {
const getStatusColor = (statusValue) => {
switch (statusValue) {
case "granted":
return "success";
case "pending":
return "warning";
case "expired":
return "default";
case "depleted":
return "default";
case "voided":
return "default";
default:
return "default";
}
};
return /* @__PURE__ */ jsx(Chip, { label: label || status, size: "small", color: getStatusColor(status) });
}
const getLink = (grant, inDashboard) => {
let path = `/customer/credit-grant/${grant.id}`;
if (inDashboard) {
path = `/admin/customers/${grant.id}`;
}
return {
link: createLink(path),
connect: false
};
};
const GrantsTable = React.memo((props) => {
const { pageSize, status = "", customer_id, subscription_id, onTableDataChange } = props;
const listKey = "credit-grants-table";
const { t, locale } = useLocaleContext();
const { session } = usePaymentContext();
const navigate = useNavigate();
const isAdmin = ["owner", "admin"].includes(session?.user?.role || "");
const inDashboard = props.mode === "dashboard" && isAdmin;
const effectiveCustomerId = customer_id || session?.user?.did;
const [search, setSearch] = useState({
pageSize: pageSize || 10,
page: 1
});
const { loading, data = { list: [], count: 0 } } = useRequest(
() => fetchData({
...search,
status,
customer_id: effectiveCustomerId,
subscription_id
}),
{
refreshDeps: [search, status, effectiveCustomerId, subscription_id]
}
);
const prevData = useRef(data);
const handleLinkClick = (e, grant) => {
const { link } = getLink(grant, inDashboard);
handleNavigation(e, link, navigate, { target: link.external ? "_blank" : "_self" });
};
useEffect(() => {
if (onTableDataChange) {
onTableDataChange(data, prevData.current);
prevData.current = data;
}
}, [data]);
const columns = [
{
label: t("common.name"),
name: "name",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: grant.name || grant.id });
}
}
},
{
label: t("common.status"),
name: "status",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: /* @__PURE__ */ jsx(StatusChip, { status: grant.status, label: t(`admin.customer.creditGrants.status.${grant.status}`) }) });
}
}
},
{
label: t("common.remainingCredit"),
name: "remaining_amount",
align: "right",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: /* @__PURE__ */ jsxs(Typography, { variant: "body2", children: [
formatBNStr(grant.remaining_amount, grant.paymentCurrency.decimal),
" ",
grant.paymentCurrency.symbol
] }) });
}
}
},
{
label: t("common.scope"),
name: "scope",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
let scope = "general";
if (grant.applicability_config?.scope?.prices) {
scope = "specific";
}
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: scope === "specific" ? t("common.specific") : t("common.general") });
}
}
},
{
label: t("common.effectiveDate"),
name: "effective_at",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
const effectiveAt = grant.effective_at ? grant.effective_at * 1e3 : grant.created_at;
return /* @__PURE__ */ jsx(Box, { onClick: (e) => handleLinkClick(e, grant), children: formatToDate(effectiveAt, locale, "YYYY-MM-DD HH:mm") });
}
}
},
{
label: t("common.expirationDate"),
name: "expires_at",
options: {
customBodyRenderLite: (_, index) => {
const grant = data?.list[index];
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") : "-" }) });
}
}
}
];
const onTableChange = ({ page, rowsPerPage }) => {
if (search.pageSize !== rowsPerPage) {
setSearch((x) => ({ ...x, pageSize: rowsPerPage, page: 1 }));
} else if (search.page !== page + 1) {
setSearch((x) => ({ ...x, page: page + 1 }));
}
};
return /* @__PURE__ */ jsx(TableRoot, { children: /* @__PURE__ */ jsx(
Table,
{
hasRowLink: true,
durable: `__${listKey}__`,
durableKeys: ["page", "rowsPerPage", "searchText"],
data: data.list,
columns,
options: {
count: data.count,
page: search.page - 1,
rowsPerPage: search.pageSize
},
loading,
onChange: onTableChange,
toolbar: false,
sx: { mt: 2 },
showMobile: false,
mobileTDFlexDirection: "row",
emptyNodeText: t("admin.creditGrants.noGrants")
}
) });
});
const TableRoot = styled(Box)`
@media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
.MuiTable-root > .MuiTableBody-root > .MuiTableRow-root > td.MuiTableCell-root {
> div {
width: fit-content;
flex: inherit;
font-size: 14px;
}
}
.invoice-summary {
padding-right: 20px;
}
}
`;
export default function CreditGrantsList(rawProps) {
const props = Object.assign(
{
customer_id: "",
subscription_id: "",
status: "granted,pending,depleted,expired",
pageSize: 10,
onTableDataChange: () => {
}
},
rawProps
);
return /* @__PURE__ */ jsx(GrantsTable, { ...props });
}