@blocklet/payment-react
Version:
Reusable react components for payment kit v2
174 lines (173 loc) • 6.22 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useState } from "react";
import AddIcon from "@mui/icons-material/Add";
import CloseIcon from "@mui/icons-material/Close";
import LocalOfferIcon from "@mui/icons-material/LocalOffer";
import {
Alert,
Box,
Button,
CircularProgress,
IconButton,
InputAdornment,
Skeleton,
Stack,
TextField,
Typography
} from "@mui/material";
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
import { formatCouponTerms } from "../../../libs/util.js";
export default function PromotionInput({
promotion,
discounts,
discountAmount,
currency = null,
initialShowInput = false,
isAmountLoading = false
}) {
const { t, locale } = useLocaleContext();
const [showInput, setShowInput] = useState(false);
const [code, setCode] = useState("");
const [applying, setApplying] = useState(false);
const [error, setError] = useState("");
const effectiveShowInput = initialShowInput || showInput;
const handleApply = async () => {
if (!code.trim()) return;
setApplying(true);
setError("");
const result = await promotion.apply(code.trim());
if (!result.success) {
setError(result.error || "Invalid code");
} else {
setCode("");
setShowInput(false);
}
setApplying(false);
};
const handleKeyPress = (event) => {
if (event.key === "Enter" && !applying && code.trim()) {
handleApply();
}
};
if (discounts?.length > 0) {
return /* @__PURE__ */ jsx(Box, { children: discounts.map((disc, i) => {
const discCode = disc.promotion_code_details?.code || disc.verification_data?.code || disc.promotion_code || "";
const coupon = disc.coupon_details || {};
const description = coupon && currency ? formatCouponTerms(coupon, currency, locale) : "";
return /* @__PURE__ */ jsxs(
Stack,
{
direction: "row",
justifyContent: "space-between",
alignItems: "center",
children: [
/* @__PURE__ */ jsxs(
Stack,
{
direction: "row",
alignItems: "center",
spacing: 0.5,
sx: {
bgcolor: (theme) => theme.palette.mode === "dark" ? "rgba(18,184,134,0.1)" : "#ebfef5",
px: 1.5,
py: 0.5,
borderRadius: "8px",
border: "1px solid",
borderColor: (theme) => theme.palette.mode === "dark" ? "rgba(18,184,134,0.2)" : "#d3f9e8"
},
children: [
/* @__PURE__ */ jsx(LocalOfferIcon, { sx: { color: "#12b886", fontSize: 14 } }),
/* @__PURE__ */ jsx(Typography, { sx: { fontWeight: 700, fontSize: 13, color: "#12b886" }, children: discCode }),
description && /* @__PURE__ */ jsxs(Typography, { sx: { fontSize: 12, color: "#12b886", fontWeight: 500, opacity: 0.8 }, children: [
"\xB7 ",
description
] }),
/* @__PURE__ */ jsx(IconButton, { size: "small", onClick: promotion.remove, sx: { width: 18, height: 18, ml: 0.25 }, children: /* @__PURE__ */ jsx(CloseIcon, { sx: { fontSize: 12, color: "#12b886" } }) })
]
}
),
isAmountLoading ? /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 80, height: 22 }) : /* @__PURE__ */ jsxs(Typography, { sx: { color: "text.primary", fontWeight: 600, fontSize: 14 }, children: [
"-",
discountAmount || "0"
] })
]
},
disc.promotion_code || disc.coupon || i
);
}) });
}
if (!promotion.active) return null;
return /* @__PURE__ */ jsx(Box, { sx: { minHeight: 36 }, children: effectiveShowInput ? /* @__PURE__ */ jsxs(
Box,
{
onBlur: (e) => {
if (initialShowInput) return;
if (!e.currentTarget.contains(e.relatedTarget) && !code.trim()) {
setShowInput(false);
}
},
children: [
/* @__PURE__ */ jsx(
TextField,
{
fullWidth: true,
size: "small",
value: code,
onChange: (e) => setCode(e.target.value),
onKeyPress: handleKeyPress,
placeholder: t("payment.checkout.promotion.placeholder"),
disabled: applying,
autoFocus: true,
slotProps: {
input: {
endAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx(
Button,
{
size: "small",
onClick: handleApply,
disabled: !code.trim() || applying,
variant: "text",
sx: {
color: "primary.main",
fontSize: 13,
textTransform: "none",
minWidth: "auto",
fontWeight: 600
},
children: applying ? /* @__PURE__ */ jsx(CircularProgress, { size: 16 }) : t("payment.checkout.promotion.apply")
}
) })
}
},
sx: {
"& .MuiOutlinedInput-root": { pr: 1, borderRadius: "8px", height: 36 },
"& .MuiOutlinedInput-input": { py: "6px", fontSize: 13 }
}
}
),
error && /* @__PURE__ */ jsx(Alert, { severity: "error", sx: { mt: 0.5, py: 0, fontSize: 12, borderRadius: "6px" }, children: error })
]
}
) : /* @__PURE__ */ jsx(
Button,
{
onClick: () => setShowInput(true),
startIcon: /* @__PURE__ */ jsx(AddIcon, { sx: { fontSize: 18 } }),
variant: "text",
sx: {
fontWeight: 600,
fontSize: 13,
textTransform: "none",
justifyContent: "flex-start",
p: 0,
height: 36,
color: "primary.main",
"&:hover": {
backgroundColor: "transparent",
textDecoration: "underline"
}
},
children: t("payment.checkout.promotion.add_code")
}
) });
}