UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

180 lines (179 loc) 5.95 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { useState } from "react"; import { Button, Typography, Stack, Alert } from "@mui/material"; import { useLocaleContext } from "@arcblock/ux/lib/Locale/context"; import Toast from "@arcblock/ux/lib/Toast"; import { joinURL } from "ufo"; import { useRequest } from "ahooks"; import { Dialog } from "@arcblock/ux"; import { usePaymentContext } from "../contexts/payment.js"; import { formatError, formatToDate, getPrefix, isCrossOrigin } from "../libs/util.js"; import api from "../libs/api.js"; import LoadingButton from "./loading-button.js"; const fetchSubscriptionDetail = async (params) => { const url = `/api/subscriptions/${params.subscriptionId}`; const res = await api.get(params.authToken ? joinURL(url, `?authToken=${params.authToken}`) : url); return res.data; }; const fetchRecoverInfo = async (params) => { const url = `/api/subscriptions/${params.subscriptionId}/recover-info`; const res = await api.get(params.authToken ? joinURL(url, `?authToken=${params.authToken}`) : url); return res.data; }; const recoverSubscription = async (params) => { const url = `/api/subscriptions/${params.subscriptionId}/recover`; const res = await api.put(params.authToken ? joinURL(url, `?authToken=${params.authToken}`) : url); return res.data; }; function RecoverSubscription({ subscriptionId, dialogProps = { open: true }, onResumed = () => { }, successToast = true, authToken = void 0 }) { const { t, locale } = useLocaleContext(); const { connect } = usePaymentContext(); const [recoverLoading, setRecoverLoading] = useState(false); const [dialogOpen, setDialogOpen] = useState(dialogProps.open || false); const { data, error, loading } = useRequest(() => fetchRecoverInfo({ subscriptionId, authToken }), { ready: !!subscriptionId }); const isCrossOriginRequest = isCrossOrigin(); const needStake = data?.needStake ?? false; const handleSuccess = async () => { try { const subscription = await fetchSubscriptionDetail({ subscriptionId, authToken }); if (successToast) { Toast.success(t("payment.customer.recover.success")); } setDialogOpen(false); onResumed(subscription); setRecoverLoading(false); } catch (err) { console.error("Failed to fetch updated subscription:", err); Toast.error(formatError(err)); setRecoverLoading(false); } }; const handleRecoverWithStake = () => { setRecoverLoading(true); try { connect.open({ locale, containerEl: void 0, saveConnect: false, action: "re-stake", prefix: joinURL(getPrefix(), "/api/did"), useSocket: !isCrossOriginRequest, extraParams: { subscriptionId }, messages: { scan: t("common.connect.defaultScan"), title: t("payment.customer.recover.reStakeTitle"), confirm: t("common.connect.confirm") }, onSuccess: handleSuccess, onClose: () => { connect.close(); setRecoverLoading(false); }, onError: (err) => { Toast.error(formatError(err)); setRecoverLoading(false); } }); } catch (err) { Toast.error(formatError(err)); setRecoverLoading(false); } }; const handleDirectRecover = async () => { setRecoverLoading(true); try { const result = await recoverSubscription({ subscriptionId, authToken }); if (result.needStake) { handleRecoverWithStake(); return; } const { subscription } = result; if (successToast) { Toast.success(t("payment.customer.recover.success")); } setDialogOpen(false); onResumed(subscription); setRecoverLoading(false); } catch (err) { Toast.error(formatError(err)); setRecoverLoading(false); } }; const handleRecover = () => { if (needStake) { handleRecoverWithStake(); } else { handleDirectRecover(); } }; const handleClose = () => { setDialogOpen(false); dialogProps.onClose?.(); }; if (loading) { return null; } return /* @__PURE__ */ jsx( Dialog, { PaperProps: { style: { minHeight: "auto" } }, ...dialogProps || {}, open: dialogOpen, title: dialogProps?.title || t("payment.customer.recover.title"), sx: { "& .MuiDialogContent-root": { pt: 0 } }, onClose: handleClose, children: error ? /* @__PURE__ */ jsx(Alert, { severity: "error", children: error.message }) : /* @__PURE__ */ jsxs( Stack, { sx: { gap: 2 }, children: [ /* @__PURE__ */ jsx( Typography, { variant: "body2", sx: { color: "text.secondary" }, children: t("payment.customer.recover.description", { date: formatToDate(Number(data?.subscription?.current_period_end || "0") * 1e3) }) } ), needStake && /* @__PURE__ */ jsx(Alert, { severity: "warning", children: t("payment.customer.recover.stakeRequiredDescription") }), /* @__PURE__ */ jsxs( Stack, { direction: "row", sx: { justifyContent: "flex-end", gap: 2, mt: 2 }, children: [ /* @__PURE__ */ jsx(Button, { variant: "outlined", color: "primary", onClick: handleClose, children: t("common.cancel") }), /* @__PURE__ */ jsx(LoadingButton, { variant: "contained", size: "small", loading: recoverLoading, onClick: handleRecover, children: t("common.confirm") }) ] } ) ] } ) } ); } export default RecoverSubscription;