UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

226 lines (225 loc) 7.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); module.exports = QuoteDetailsPanel; var _jsxRuntime = require("react/jsx-runtime"); var _ExpandMore = _interopRequireDefault(require("@mui/icons-material/ExpandMore")); var _InfoOutlined = _interopRequireDefault(require("@mui/icons-material/InfoOutlined")); var _Settings = _interopRequireDefault(require("@mui/icons-material/Settings")); var _material = require("@mui/material"); var _react = require("react"); var _context = require("@arcblock/ux/lib/Locale/context"); var _slippageConfig = _interopRequireDefault(require("./slippage-config")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function QuoteDetailsPanel({ rateLine, rows, isSubscription = false, slippageValue = 0.5, onSlippageChange = void 0, slippageConfig = void 0, exchangeRate = null, baseCurrency = "USD", disabled = false }) { const { t } = (0, _context.useLocaleContext)(); const [open, setOpen] = (0, _react.useState)(false); const [showContent, setShowContent] = (0, _react.useState)(true); const [dialogOpen, setDialogOpen] = (0, _react.useState)(false); const [pendingConfig, setPendingConfig] = (0, _react.useState)(null); const [submitting, setSubmitting] = (0, _react.useState)(false); const hasRows = rows.length > 0; const handleOpenDialog = (0, _react.useCallback)(() => { setPendingConfig(slippageConfig || { mode: "percent", percent: slippageValue }); setDialogOpen(true); }, [slippageValue, slippageConfig]); const handleCloseDialog = () => { setDialogOpen(false); setPendingConfig(null); }; const handleSlippageChange = value => { setPendingConfig(prev => prev ? { ...prev, percent: value } : { mode: "percent", percent: value }); }; const handleConfigChange = config => { setPendingConfig(config); }; const handleSubmit = async () => { if (!pendingConfig || !onSlippageChange) return; setSubmitting(true); try { const configToSave = { ...pendingConfig, ...(baseCurrency ? { base_currency: baseCurrency } : {}) }; await onSlippageChange(configToSave); setDialogOpen(false); setPendingConfig(null); } catch (err) { console.error("Failed to update slippage", err); } finally { setSubmitting(false); } }; (0, _react.useEffect)(() => { if (!rateLine) return void 0; setShowContent(false); const timer = setTimeout(() => { setShowContent(true); }, 150); return () => clearTimeout(timer); }, [rateLine]); const renderedRows = (0, _react.useMemo)(() => rows.map(row => { const isSlippageRow = row.isSlippage && isSubscription && onSlippageChange; return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { direction: "row", sx: { alignItems: "center", justifyContent: "space-between", gap: 2 }, children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { direction: "row", spacing: 0.5, alignItems: "center", children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, { sx: { fontSize: "0.75rem", color: "text.secondary" }, children: row.label }), row.tooltip && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Tooltip, { title: row.tooltip, placement: "top", children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_InfoOutlined.default, { sx: { fontSize: "0.75rem", color: "text.lighter" } }) })] }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, { sx: { fontSize: "0.75rem", color: "text.primary" }, children: row.value }), isSlippageRow && !disabled && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.IconButton, { size: "small", onClick: handleOpenDialog, sx: { p: 0.25 }, children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_Settings.default, { sx: { fontSize: "0.875rem", color: "text.secondary" } }) })] })] }, row.label); }), [rows, isSubscription, onSlippageChange, disabled, handleOpenDialog]); const showSlippageOnly = !rateLine && isSubscription && onSlippageChange && rows.some(r => r.isSlippage); if (!rateLine && !showSlippageOnly) { return null; } return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Box, { sx: { width: "100%", mt: 0.5 }, children: [/* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, { direction: "row", sx: { alignItems: "center", justifyContent: "space-between", gap: 1 }, children: [rateLine ? /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Fade, { in: showContent, timeout: 300, children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Typography, { sx: { fontSize: "0.7875rem", color: "text.lighter" }, children: rateLine }) }) : /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Box, {}), hasRows && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.IconButton, { size: "small", onClick: () => setOpen(prev => !prev), "aria-label": open ? "collapse" : "expand", children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_ExpandMore.default, { sx: { fontSize: "1rem", transition: "transform 0.2s ease", transform: open ? "rotate(180deg)" : "rotate(0deg)" } }) })] }), hasRows && /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Collapse, { in: open, timeout: "auto", unmountOnExit: true, children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Fade, { in: showContent, timeout: 300, children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.Stack, { sx: { mt: 1, p: 1.25, borderRadius: 1, border: "1px solid", borderColor: "divider", bgcolor: "action.hover" }, spacing: 1, children: renderedRows }) }) })] }), /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Dialog, { open: dialogOpen, onClose: handleCloseDialog, maxWidth: "sm", fullWidth: true, children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_material.DialogTitle, { children: t("payment.checkout.quote.slippage.title") }), /* @__PURE__ */(0, _jsxRuntime.jsx)(_material.DialogContent, { children: /* @__PURE__ */(0, _jsxRuntime.jsx)(_slippageConfig.default, { value: pendingConfig?.percent ?? slippageValue, onChange: handleSlippageChange, config: pendingConfig || slippageConfig, onConfigChange: handleConfigChange, exchangeRate, baseCurrency, disabled: disabled || submitting, sx: { mt: 1 }, onCancel: handleCloseDialog, onSave: handleSubmit }) })] })] }); }