@blocklet/payment-react
Version:
Reusable react components for payment kit v2
170 lines (169 loc) • 8.05 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useState, useRef, useCallback, useEffect } from "react";
import { Box, Button, InputBase, InputAdornment, Stack, Typography } from "@mui/material";
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
import CountrySelect from "../../../components/country-select.js";
import PhoneField from "../../../components/phone-field.js";
import { countryCodeToFlag } from "../../utils/format.js";
const fieldLabelMap = (t) => ({
customer_name: t("payment.checkout.customer.name"),
customer_email: t("payment.checkout.customer.email"),
customer_phone: t("payment.checkout.customer.phone"),
"billing_address.country": t("payment.checkout.billing.country"),
"billing_address.state": t("payment.checkout.billing.state"),
"billing_address.city": t("payment.checkout.billing.city"),
"billing_address.line1": t("payment.checkout.billing.line1"),
"billing_address.line2": t("payment.checkout.billing.line2"),
"billing_address.postal_code": t("payment.checkout.billing.postal_code")
});
export default function CustomerInfoCard({ form, isLoggedIn }) {
const { t } = useLocaleContext();
const labels = fieldLabelMap(t);
const [showEditForm, setShowEditForm] = useState(false);
const [ready, setReady] = useState(false);
const checkedRef = useRef(false);
useEffect(() => {
if (checkedRef.current) return;
if (!form.prefetched && !form.values.customer_name && !form.values.customer_email) return;
checkedRef.current = true;
form.checkValid().then((valid) => {
setShowEditForm(!valid);
setReady(true);
});
}, [form.prefetched]);
const handleChange = useCallback(
(field, value) => form.onChange(field, value),
[form.onChange]
// eslint-disable-line react-hooks/exhaustive-deps
);
useEffect(() => {
if (ready && !showEditForm && Object.keys(form.errors).length > 0) {
setShowEditForm(true);
}
}, [form.errors]);
if (!isLoggedIn || !ready) return null;
if (!showEditForm) {
return /* @__PURE__ */ jsxs(Box, { sx: { mt: 2 }, children: [
/* @__PURE__ */ jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { mb: 1 }, children: [
/* @__PURE__ */ jsx(Typography, { sx: { fontSize: 13, fontWeight: 600, color: "text.secondary" }, children: t("payment.checkout.customerInfo") }),
/* @__PURE__ */ jsx(
Button,
{
size: "small",
variant: "text",
onClick: () => setShowEditForm(true),
sx: { minWidth: 0, fontSize: 13, fontWeight: 600, p: 0 },
children: t("common.edit")
}
)
] }),
/* @__PURE__ */ jsxs(
Stack,
{
spacing: 0.5,
sx: {
p: 2,
backgroundColor: "background.paper",
borderRadius: 1,
border: "1px solid",
borderColor: "divider"
},
children: [
form.values.customer_name && /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.primary", fontWeight: 600, fontSize: "0.9375rem" }, children: form.values.customer_name }),
form.values.customer_email && /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.8125rem" }, children: form.values.customer_email }),
form.fields.some((f) => f.name === "customer_phone") && form.values.customer_phone && /* @__PURE__ */ jsx(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.8125rem" }, children: form.values.customer_phone }),
(form.values.billing_address?.country || form.values.billing_address?.state || form.values.billing_address?.postal_code) && /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.75, children: [
form.values.billing_address?.country && /* @__PURE__ */ jsx(Box, { component: "span", sx: { fontSize: 14, lineHeight: 1 }, children: countryCodeToFlag(form.values.billing_address.country) }),
/* @__PURE__ */ jsxs(Typography, { variant: "body2", sx: { color: "text.secondary", fontSize: "0.8125rem" }, children: [
form.values.billing_address?.state || "",
form.values.billing_address?.postal_code ? ` [ ${t("payment.checkout.billing.postal_code")}: ${form.values.billing_address.postal_code} ]` : ""
] })
] })
]
}
)
] });
}
return /* @__PURE__ */ jsxs(Box, { sx: { mt: 2 }, children: [
/* @__PURE__ */ jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { mb: 1 }, children: [
/* @__PURE__ */ jsx(Typography, { sx: { fontSize: 13, fontWeight: 600, color: "text.secondary" }, children: t("payment.checkout.customerInfo") }),
/* @__PURE__ */ jsx(
Button,
{
size: "small",
variant: "text",
onClick: () => setShowEditForm(false),
sx: { minWidth: 0, fontSize: 13, fontWeight: 600, p: 0 },
children: t("common.confirm")
}
)
] }),
/* @__PURE__ */ jsx(
Stack,
{
spacing: 0,
sx: {
p: 2,
backgroundColor: "background.paper",
borderRadius: 1,
border: "1px solid",
borderColor: "divider"
},
children: form.fields.filter((f) => f.name !== "billing_address.country").map((field) => {
const { name } = field;
const label = labels[name] || name;
const value = name.includes(".") ? name.split(".").reduce((o, k) => o?.[k], form.values) : form.values[name];
const isPostalCode = name === "billing_address.postal_code";
const isPhone = name === "customer_phone";
if (isPhone) {
return /* @__PURE__ */ jsx(
PhoneField,
{
value: value || "",
country: form.values.billing_address?.country || "",
onChange: (phone) => handleChange("customer_phone", phone),
onCountryChange: (c) => handleChange("billing_address.country", c),
onBlur: () => form.validateField(name),
label,
error: form.errors[name]
},
name
);
}
return /* @__PURE__ */ jsxs(Box, { sx: { mb: 1.5 }, children: [
/* @__PURE__ */ jsx(Typography, { sx: { fontSize: 13, fontWeight: 600, color: "text.primary", mb: 0.5 }, children: label }),
/* @__PURE__ */ jsx(
InputBase,
{
fullWidth: true,
value: value || "",
onChange: (e) => handleChange(name, e.target.value),
onBlur: () => form.validateField(name),
startAdornment: isPostalCode ? /* @__PURE__ */ jsx(InputAdornment, { position: "start", sx: { mr: 0.5, ml: -0.5 }, children: /* @__PURE__ */ jsx(
CountrySelect,
{
value: form.values.billing_address?.country || "",
onChange: (v) => handleChange("billing_address.country", v),
sx: {
".MuiOutlinedInput-notchedOutline": { borderColor: "transparent !important" },
"& .MuiSelect-select": { py: 0, pr: "20px !important" }
}
}
) }) : void 0,
sx: {
bgcolor: (theme) => theme.palette.mode === "dark" ? "rgba(255,255,255,0.06)" : "grey.50",
borderRadius: "8px",
px: 1.5,
py: 0.75,
fontSize: 14,
"& .MuiInputBase-input": { p: 0 }
}
}
),
form.errors[name] && /* @__PURE__ */ jsx(Typography, { sx: { fontSize: 12, color: "error.main", mt: 0.25 }, children: form.errors[name] })
] }, name);
})
}
)
] });
}