UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

170 lines (169 loc) 8.05 kB
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); }) } ) ] }); }