@blocklet/payment-react
Version:
Reusable react components for payment kit v2
226 lines (225 loc) • 7.66 kB
JavaScript
"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
})
})]
})]
});
}