@blocklet/payment-react
Version:
Reusable react components for payment kit v2
141 lines (140 loc) • 5.58 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
import { Box, LinearProgress, Skeleton, Typography } from "@mui/material";
import { useCallback, useEffect, useRef, useState } from "react";
import { Check } from "@mui/icons-material";
export function VendorPlaceholder() {
return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
/* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 16, width: 150 }),
/* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 16, width: 50 })
] }),
/* @__PURE__ */ jsx(Skeleton, { variant: "rounded", height: 8, width: "100%" })
] });
}
const getVendorLabel = (vendor, isFailed, t) => {
const name = vendor.name || vendor.title;
const isCompleted = vendor.status === "delivered";
if (vendor.vendorType === "didnames") {
if (isFailed) {
return t("payment.checkout.vendor.didnames.failed", { name });
}
if (isCompleted) {
return t("payment.checkout.vendor.didnames.completed", { name });
}
return t("payment.checkout.vendor.didnames.processing", { name });
}
if (isFailed) {
return t("payment.checkout.vendor.launcher.failed", { name });
}
if (isCompleted) {
return t("payment.checkout.vendor.launcher.completed", { name });
}
return t("payment.checkout.vendor.launcher.processing", { name });
};
export function VendorProgressItem({ vendor }) {
const { t } = useLocaleContext();
const [displayProgress, setDisplayProgress] = useState(0);
const animationRef = useRef();
const startAnimation = useCallback(() => {
const realProgress = vendor.progress || 0;
let startTime;
let startProgress;
const animate = (currentTime) => {
if (!startTime) {
startTime = currentTime;
startProgress = displayProgress;
}
const elapsed = currentTime - startTime;
let newProgress;
if (realProgress === 100) {
newProgress = 100;
} else if (realProgress === 0) {
newProgress = Math.min(startProgress + elapsed / 1e3, 99);
} else if (realProgress > startProgress) {
const duration = 1e3;
const progress = Math.min(elapsed / duration, 1);
newProgress = startProgress + (realProgress - startProgress) * progress;
} else {
newProgress = Math.min(startProgress + elapsed / 1e3, 99);
}
newProgress = Math.round(newProgress);
setDisplayProgress((pre) => Math.min(pre > newProgress ? pre : newProgress, 100));
if (realProgress === 100) {
return;
}
if (newProgress < 99 && realProgress < 100) {
animationRef.current = requestAnimationFrame(animate);
}
};
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
}
animationRef.current = requestAnimationFrame(animate);
}, [vendor.progress, displayProgress]);
useEffect(() => {
startAnimation();
return () => {
if (animationRef.current) {
cancelAnimationFrame(animationRef.current);
}
};
}, [startAnimation]);
const isCompleted = displayProgress >= 100;
const isFailed = vendor.status === "failed";
const nameText = getVendorLabel(vendor, isFailed, t);
if (isFailed) {
return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
/* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary" }, children: nameText }),
/* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "error.main", fontWeight: 500 }, children: t("payment.checkout.vendor.progress", { progress: 0 }) })
] }),
/* @__PURE__ */ jsx(
LinearProgress,
{
variant: "determinate",
value: 100,
sx: {
height: 8,
borderRadius: 4,
backgroundColor: "grey.200",
"& .MuiLinearProgress-bar": {
borderRadius: 4,
backgroundColor: "error.main"
}
}
}
)
] });
}
if (!vendor.name && !vendor.title) {
return /* @__PURE__ */ jsx(VendorPlaceholder, {});
}
return /* @__PURE__ */ jsxs(Box, { sx: { mb: 2 }, children: [
/* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 1 }, children: [
/* @__PURE__ */ jsxs(Typography, { variant: "body2", sx: { color: "text.secondary", display: "flex", alignItems: "center" }, children: [
nameText,
" ",
isCompleted ? /* @__PURE__ */ jsx(Check, { sx: { color: "success.main", ml: 0.5 }, fontSize: "small" }) : null
] }),
isCompleted ? null : /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", fontWeight: 500 }, children: t("payment.checkout.vendor.progress", { progress: displayProgress }) })
] }),
/* @__PURE__ */ jsx(
LinearProgress,
{
variant: "determinate",
value: displayProgress || 0,
sx: {
height: 8,
borderRadius: 4,
backgroundColor: "grey.200",
"& .MuiLinearProgress-bar": {
borderRadius: 4,
backgroundColor: isCompleted ? "success.main" : "primary.main",
transition: "background-color 0.3s linear"
}
}
}
)
] });
}