UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

154 lines (153 loc) 4.68 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { useLocaleContext } from "@arcblock/ux/lib/Locale/context"; import { TextField, Button, Alert, Box, InputAdornment } from "@mui/material"; import { Add } from "@mui/icons-material"; import { useState } from "react"; import LoadingButton from "./loading-button.js"; import api from "../libs/api.js"; import { usePaymentContext } from "../contexts/payment.js"; export default function PromotionCode({ checkoutSessionId, initialAppliedCodes = [], disabled = false, className = "", placeholder = "", onUpdate = void 0, currencyId }) { const { t } = useLocaleContext(); const [showInput, setShowInput] = useState(false); const [code, setCode] = useState(""); const [error, setError] = useState(""); const [applying, setApplying] = useState(false); const [appliedCodes, setAppliedCodes] = useState(initialAppliedCodes); const { session, paymentState } = usePaymentContext(); const handleLoginCheck = () => { if (!session.user) { session?.login(() => { handleApply(); }); } else { handleApply(); } }; const handleApply = async () => { if (!code.trim()) return; if (paymentState.paying || paymentState.stripePaying) { return; } setApplying(true); setError(""); try { const response = await api.post(`/api/checkout-sessions/${checkoutSessionId}/apply-promotion`, { promotion_code: code.trim(), currency_id: currencyId }); const discounts = response.data.discounts || []; const appliedDiscount = discounts[0]; if (appliedDiscount) { const newCode = { id: appliedDiscount.promotion_code || appliedDiscount.coupon, code: code.trim(), discount_amount: appliedDiscount.discount_amount }; setAppliedCodes([newCode]); setCode(""); setShowInput(false); onUpdate?.({ appliedCodes: [newCode], discountAmount: appliedDiscount.discount_amount }); } } catch (err) { const errorMessage = err.response?.data?.error || err.message; setError(errorMessage); } finally { setApplying(false); } }; const handleKeyPress = (event) => { if (event.key === "Enter" && !applying && code.trim()) { handleLoginCheck(); } }; const isPaymentInProgress = paymentState.paying || paymentState.stripePaying; return /* @__PURE__ */ jsx(Box, { className, children: appliedCodes.length === 0 && !disabled && !isPaymentInProgress && (showInput ? /* @__PURE__ */ jsxs( Box, { onBlur: () => { if (!code.trim()) { setShowInput(false); } }, children: [ /* @__PURE__ */ jsx( TextField, { fullWidth: true, value: code, onChange: (e) => setCode(e.target.value), onKeyPress: handleKeyPress, placeholder: placeholder || t("payment.checkout.promotion.placeholder"), variant: "outlined", size: "small", disabled: applying, autoFocus: true, slotProps: { input: { endAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "end", children: /* @__PURE__ */ jsx( LoadingButton, { size: "small", onClick: handleLoginCheck, loading: applying, disabled: !code.trim(), variant: "text", sx: { color: "primary.main", fontSize: "small" }, children: t("payment.checkout.promotion.apply") } ) }) } }, sx: { "& .MuiOutlinedInput-root": { pr: 1 } } } ), error && /* @__PURE__ */ jsx( Alert, { severity: "error", sx: { my: 1 }, children: error } ) ] } ) : /* @__PURE__ */ jsx( Button, { onClick: () => setShowInput(true), startIcon: /* @__PURE__ */ jsx(Add, { fontSize: "small" }), variant: "text", sx: { fontWeight: "normal", textTransform: "none", justifyContent: "flex-start", p: 0, "&:hover": { backgroundColor: "transparent", textDecoration: "underline" } }, children: t("payment.checkout.promotion.add_code") } )) }); }