UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

141 lines (140 loc) 5.58 kB
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" } } } ) ] }); }