@blocklet/payment-react 1.14.29 → 1.14.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/checkout/table.js +3 -2
- package/es/components/pricing-table.js +2 -1
- package/es/components/truncated-text.d.ts +15 -0
- package/es/components/truncated-text.js +27 -0
- package/es/history/invoice/list.js +14 -4
- package/es/index.d.ts +2 -1
- package/es/index.js +3 -1
- package/es/libs/util.d.ts +2 -0
- package/es/libs/util.js +33 -0
- package/es/locales/en.js +3 -1
- package/es/locales/zh.js +3 -1
- package/es/payment/form/index.js +89 -60
- package/es/payment/index.js +81 -15
- package/es/payment/summary.js +2 -18
- package/es/theme/index.js +5 -0
- package/lib/checkout/table.js +8 -2
- package/lib/components/pricing-table.js +6 -1
- package/lib/components/truncated-text.d.ts +15 -0
- package/lib/components/truncated-text.js +55 -0
- package/lib/history/invoice/list.js +8 -3
- package/lib/index.d.ts +2 -1
- package/lib/index.js +8 -0
- package/lib/libs/util.d.ts +2 -0
- package/lib/libs/util.js +35 -0
- package/lib/locales/en.js +3 -1
- package/lib/locales/zh.js +3 -1
- package/lib/payment/form/index.js +37 -11
- package/lib/payment/index.js +59 -4
- package/lib/payment/summary.js +2 -6
- package/lib/theme/index.js +5 -0
- package/package.json +8 -8
- package/src/checkout/table.tsx +3 -2
- package/src/components/pricing-table.tsx +2 -1
- package/src/components/truncated-text.tsx +41 -0
- package/src/history/invoice/list.tsx +9 -4
- package/src/index.ts +2 -0
- package/src/libs/util.ts +41 -0
- package/src/locales/en.tsx +3 -0
- package/src/locales/zh.tsx +2 -0
- package/src/payment/form/index.tsx +43 -15
- package/src/payment/index.tsx +70 -5
- package/src/payment/summary.tsx +2 -8
- package/src/theme/index.tsx +5 -0
package/es/checkout/table.js
CHANGED
|
@@ -11,6 +11,7 @@ import api from "../libs/api.js";
|
|
|
11
11
|
import { mergeExtraParams } from "../libs/util.js";
|
|
12
12
|
import CheckoutForm from "./form.js";
|
|
13
13
|
import { PaymentThemeProvider } from "../theme/index.js";
|
|
14
|
+
import TruncatedText from "../components/truncated-text.js";
|
|
14
15
|
const fetchData = async (id) => {
|
|
15
16
|
const { data } = await api.get(`/api/pricing-tables/${id}`);
|
|
16
17
|
return data;
|
|
@@ -85,7 +86,7 @@ function CheckoutTableInner({ id, mode, onPaid, onError, onChange, extraParams,
|
|
|
85
86
|
textAlign: "center"
|
|
86
87
|
},
|
|
87
88
|
children: [
|
|
88
|
-
!data.livemode && /* @__PURE__ */ jsx(Livemode, { sx: { display: "flex", marginBottom: "8px", width: "fit-content" } }),
|
|
89
|
+
!data.livemode && /* @__PURE__ */ jsx(Livemode, { sx: { display: "flex", marginBottom: "8px", width: "fit-content", ml: 0 } }),
|
|
89
90
|
/* @__PURE__ */ jsx(
|
|
90
91
|
Typography,
|
|
91
92
|
{
|
|
@@ -95,7 +96,7 @@ function CheckoutTableInner({ id, mode, onPaid, onError, onChange, extraParams,
|
|
|
95
96
|
lineHeight: "32px",
|
|
96
97
|
fontSize: "24px"
|
|
97
98
|
},
|
|
98
|
-
children: data.name
|
|
99
|
+
children: /* @__PURE__ */ jsx(TruncatedText, { text: data.name, maxLength: 60, useWidth: true })
|
|
99
100
|
}
|
|
100
101
|
)
|
|
101
102
|
]
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
} from "../libs/util.js";
|
|
33
33
|
import Amount from "../payment/amount.js";
|
|
34
34
|
import { useMobile } from "../hooks/mobile.js";
|
|
35
|
+
import TruncatedText from "./truncated-text.js";
|
|
35
36
|
const sortOrder = {
|
|
36
37
|
year: 1,
|
|
37
38
|
month: 2,
|
|
@@ -294,7 +295,7 @@ export default function PricingTable({ table, alignItems, interval, mode, onSele
|
|
|
294
295
|
fontSize: "18px !important",
|
|
295
296
|
fontWeight: "600"
|
|
296
297
|
},
|
|
297
|
-
children: x.product.name
|
|
298
|
+
children: /* @__PURE__ */ jsx(TruncatedText, { text: x.product.name, maxLength: 26, useWidth: true })
|
|
298
299
|
}
|
|
299
300
|
),
|
|
300
301
|
x.is_highlight && /* @__PURE__ */ jsx(
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface TruncatedTextProps {
|
|
3
|
+
text?: string;
|
|
4
|
+
maxLength?: number;
|
|
5
|
+
useWidth?: boolean;
|
|
6
|
+
}
|
|
7
|
+
declare function TruncatedText({ text, maxLength, useWidth }: TruncatedTextProps): import("react").JSX.Element | null;
|
|
8
|
+
declare namespace TruncatedText {
|
|
9
|
+
var defaultProps: {
|
|
10
|
+
useWidth: boolean;
|
|
11
|
+
text: string;
|
|
12
|
+
maxLength: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export default TruncatedText;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Tooltip, tooltipClasses } from "@mui/material";
|
|
3
|
+
import { styled } from "@mui/system";
|
|
4
|
+
import { truncateText } from "../libs/util.js";
|
|
5
|
+
const CustomTooltip = styled(({ className, ...props }) => /* @__PURE__ */ jsx(Tooltip, { ...props, classes: { popper: className } }))({
|
|
6
|
+
[`& .${tooltipClasses.tooltip}`]: {
|
|
7
|
+
fontSize: 11,
|
|
8
|
+
maxHeight: 120,
|
|
9
|
+
maxWidth: 500,
|
|
10
|
+
overflowY: "auto"
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
export default function TruncatedText({ text = "", maxLength = 100, useWidth = false }) {
|
|
14
|
+
if (!text) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const truncatedText = truncateText(text, maxLength, useWidth);
|
|
18
|
+
if (!truncatedText.endsWith("...")) {
|
|
19
|
+
return /* @__PURE__ */ jsx("span", { children: truncatedText });
|
|
20
|
+
}
|
|
21
|
+
return /* @__PURE__ */ jsx(CustomTooltip, { title: text, placement: "bottom", enterTouchDelay: 0, children: /* @__PURE__ */ jsx("span", { title: text, children: truncatedText }) });
|
|
22
|
+
}
|
|
23
|
+
TruncatedText.defaultProps = {
|
|
24
|
+
useWidth: false,
|
|
25
|
+
text: "",
|
|
26
|
+
maxLength: 100
|
|
27
|
+
};
|
|
@@ -96,7 +96,7 @@ const InvoiceTable = React.memo((props) => {
|
|
|
96
96
|
{
|
|
97
97
|
label: t("common.amount"),
|
|
98
98
|
name: "total",
|
|
99
|
-
width:
|
|
99
|
+
width: 80,
|
|
100
100
|
align: "right",
|
|
101
101
|
options: {
|
|
102
102
|
customBodyRenderLite: (_, index) => {
|
|
@@ -146,9 +146,8 @@ const InvoiceTable = React.memo((props) => {
|
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
148
|
label: t("common.status"),
|
|
149
|
-
name: "
|
|
149
|
+
name: "status",
|
|
150
150
|
options: {
|
|
151
|
-
sort: true,
|
|
152
151
|
customBodyRenderLite: (val, index) => {
|
|
153
152
|
const invoice = data?.list[index];
|
|
154
153
|
const link = getInvoiceLink(invoice, action);
|
|
@@ -300,7 +299,17 @@ const InvoiceList = React.memo((props) => {
|
|
|
300
299
|
] }) }),
|
|
301
300
|
/* @__PURE__ */ jsx(Box, { flex: 1, textAlign: "right", children: /* @__PURE__ */ jsx(Typography, { children: formatToDate(invoice.created_at, locale, "HH:mm:ss") }) }),
|
|
302
301
|
!action && /* @__PURE__ */ jsx(Hidden, { mdDown: true, children: /* @__PURE__ */ jsx(Box, { flex: 2, className: "invoice-description", textAlign: "right", children: /* @__PURE__ */ jsx(Typography, { children: invoice.description || invoice.id }) }) }),
|
|
303
|
-
/* @__PURE__ */ jsx(Box, { flex: 1, textAlign: "right", children: action ? link.connect ? /* @__PURE__ */ jsx(
|
|
302
|
+
/* @__PURE__ */ jsx(Box, { flex: 1, textAlign: "right", children: action ? link.connect ? /* @__PURE__ */ jsx(
|
|
303
|
+
Button,
|
|
304
|
+
{
|
|
305
|
+
variant: "contained",
|
|
306
|
+
color: "primary",
|
|
307
|
+
size: "small",
|
|
308
|
+
onClick: () => onPay(invoice.id),
|
|
309
|
+
sx: { whiteSpace: "nowrap" },
|
|
310
|
+
children: t("payment.customer.invoice.pay")
|
|
311
|
+
}
|
|
312
|
+
) : /* @__PURE__ */ jsx(
|
|
304
313
|
Button,
|
|
305
314
|
{
|
|
306
315
|
component: "a",
|
|
@@ -308,6 +317,7 @@ const InvoiceList = React.memo((props) => {
|
|
|
308
317
|
size: "small",
|
|
309
318
|
href: link.url,
|
|
310
319
|
target: link.external ? "_blank" : target,
|
|
320
|
+
sx: { whiteSpace: "nowrap" },
|
|
311
321
|
rel: "noreferrer",
|
|
312
322
|
children: t("payment.customer.invoice.pay")
|
|
313
323
|
}
|
package/es/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ import ProductSkeleton from './payment/product-skeleton';
|
|
|
25
25
|
import PaymentSummary from './payment/summary';
|
|
26
26
|
import PricingItem from './components/pricing-item';
|
|
27
27
|
import CountrySelect from './components/country-select';
|
|
28
|
+
import TruncatedText from './components/truncated-text';
|
|
28
29
|
export { PaymentThemeProvider } from './theme';
|
|
29
30
|
export * from './libs/util';
|
|
30
31
|
export * from './libs/connect';
|
|
@@ -33,4 +34,4 @@ export * from './hooks/subscription';
|
|
|
33
34
|
export * from './hooks/mobile';
|
|
34
35
|
export * from './hooks/table';
|
|
35
36
|
export { translations, createTranslator } from './locales';
|
|
36
|
-
export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, };
|
|
37
|
+
export { api, dayjs, FormInput, PhoneInput, AddressForm, StripeForm, Status, Livemode, Switch, ConfirmDialog, CheckoutForm, CheckoutTable, CheckoutDonate, CurrencySelector, Payment, PaymentSummary, PricingTable, ProductSkeleton, Amount, CustomerInvoiceList, CustomerPaymentList, TxLink, TxGas, SafeGuard, PricingItem, CountrySelect, Table, TruncatedText, };
|
package/es/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import ProductSkeleton from "./payment/product-skeleton.js";
|
|
|
25
25
|
import PaymentSummary from "./payment/summary.js";
|
|
26
26
|
import PricingItem from "./components/pricing-item.js";
|
|
27
27
|
import CountrySelect from "./components/country-select.js";
|
|
28
|
+
import TruncatedText from "./components/truncated-text.js";
|
|
28
29
|
export { PaymentThemeProvider } from "./theme/index.js";
|
|
29
30
|
export * from "./libs/util.js";
|
|
30
31
|
export * from "./libs/connect.js";
|
|
@@ -60,5 +61,6 @@ export {
|
|
|
60
61
|
SafeGuard,
|
|
61
62
|
PricingItem,
|
|
62
63
|
CountrySelect,
|
|
63
|
-
Table
|
|
64
|
+
Table,
|
|
65
|
+
TruncatedText
|
|
64
66
|
};
|
package/es/libs/util.d.ts
CHANGED
|
@@ -105,3 +105,5 @@ export declare function formatQuantityInventory(price: TPrice, quantity: string
|
|
|
105
105
|
export declare function formatSubscriptionStatus(status: string): string;
|
|
106
106
|
export declare function formatAmountPrecisionLimit(amount: string, locale?: string, precision?: number): string;
|
|
107
107
|
export declare function getWordBreakStyle(value: any): 'break-word' | 'break-all';
|
|
108
|
+
export declare function isMobileSafari(): boolean;
|
|
109
|
+
export declare function truncateText(text: string, maxLength: number, useWidth?: boolean): string;
|
package/es/libs/util.js
CHANGED
|
@@ -2,6 +2,7 @@ import { BN, fromUnitToToken } from "@ocap/util";
|
|
|
2
2
|
import omit from "lodash/omit";
|
|
3
3
|
import trimEnd from "lodash/trimEnd";
|
|
4
4
|
import numbro from "numbro";
|
|
5
|
+
import stringWidth from "string-width";
|
|
5
6
|
import { defaultCountries } from "react-international-phone";
|
|
6
7
|
import { joinURL } from "ufo";
|
|
7
8
|
import { t } from "../locales/index.js";
|
|
@@ -805,3 +806,35 @@ export function getWordBreakStyle(value) {
|
|
|
805
806
|
}
|
|
806
807
|
return "break-all";
|
|
807
808
|
}
|
|
809
|
+
export function isMobileSafari() {
|
|
810
|
+
const ua = navigator.userAgent.toLowerCase();
|
|
811
|
+
const isSafari = ua.indexOf("safari") > -1 && ua.indexOf("chrome") === -1;
|
|
812
|
+
const isMobile = ua.indexOf("mobile") > -1 || /iphone|ipad|ipod/.test(ua);
|
|
813
|
+
const isIOS = /iphone|ipad|ipod/.test(ua);
|
|
814
|
+
return isSafari && isMobile && isIOS;
|
|
815
|
+
}
|
|
816
|
+
export function truncateText(text, maxLength, useWidth = false) {
|
|
817
|
+
if (!text || !maxLength) {
|
|
818
|
+
return text;
|
|
819
|
+
}
|
|
820
|
+
if (!useWidth) {
|
|
821
|
+
if (text.length <= maxLength) {
|
|
822
|
+
return text;
|
|
823
|
+
}
|
|
824
|
+
return `${text.substring(0, maxLength)}...`;
|
|
825
|
+
}
|
|
826
|
+
let width = 0;
|
|
827
|
+
let truncated = "";
|
|
828
|
+
for (let i = 0; i < text.length; i++) {
|
|
829
|
+
const charWidth = stringWidth(text.charAt(i));
|
|
830
|
+
if (width + charWidth > maxLength) {
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
truncated += text.charAt(i);
|
|
834
|
+
width += charWidth;
|
|
835
|
+
}
|
|
836
|
+
if (truncated === text) {
|
|
837
|
+
return truncated;
|
|
838
|
+
}
|
|
839
|
+
return `${truncated}...`;
|
|
840
|
+
}
|
package/es/locales/en.js
CHANGED
|
@@ -202,6 +202,7 @@ export default flat({
|
|
|
202
202
|
title: "Cancel your subscription",
|
|
203
203
|
comment: "Any additional feedback?",
|
|
204
204
|
description: "Your subscription will be canceled, but it is still available until the end of your current billing period on {date}",
|
|
205
|
+
trialDescription: "Free trial subscriptions will be canceled immediately and no longer available, confirm to continue",
|
|
205
206
|
feedback: {
|
|
206
207
|
tip: "We would love your feedback, it will help us improve our service",
|
|
207
208
|
too_expensive: "The service is too expensive",
|
|
@@ -303,7 +304,8 @@ export default flat({
|
|
|
303
304
|
threshold: "Metered usage billing",
|
|
304
305
|
cancel: "Subscription cancel",
|
|
305
306
|
manual: "Manual invoice",
|
|
306
|
-
upcoming: "Upcoming invoice"
|
|
307
|
+
upcoming: "Upcoming invoice",
|
|
308
|
+
slashStake: "Slash stake"
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
311
|
},
|
package/es/locales/zh.js
CHANGED
|
@@ -202,6 +202,7 @@ export default flat({
|
|
|
202
202
|
title: "\u53D6\u6D88\u60A8\u7684\u8BA2\u9605",
|
|
203
203
|
comment: "\u4F60\u8FD8\u6709\u5176\u4ED6\u53CD\u9988\u4E48\uFF1F",
|
|
204
204
|
description: "\u60A8\u7684\u8BA2\u9605\u5C06\u88AB\u53D6\u6D88\uFF0C\u4F46\u4ECD\u7136\u53EF\u7528\u76F4\u5230\u60A8\u5F53\u524D\u8BA1\u8D39\u5468\u671F\u7ED3\u675F\u4E8E{date}",
|
|
205
|
+
trialDescription: "\u514D\u8D39\u8BD5\u7528\u7684\u8BA2\u9605\u5C06\u88AB\u7ACB\u5373\u53D6\u6D88\uFF0C\u4E0D\u518D\u53EF\u7528\uFF0C\u786E\u8BA4\u662F\u5426\u7EE7\u7EED",
|
|
205
206
|
feedback: {
|
|
206
207
|
tip: "\u6211\u4EEC\u5E0C\u671B\u542C\u5230\u60A8\u7684\u53CD\u9988\uFF0C\u8FD9\u5C06\u5E2E\u52A9\u6211\u4EEC\u6539\u8FDB\u6211\u4EEC\u7684\u670D\u52A1",
|
|
207
208
|
too_expensive: "\u670D\u52A1\u8D39\u7528\u592A\u9AD8",
|
|
@@ -303,7 +304,8 @@ export default flat({
|
|
|
303
304
|
threshold: "\u7528\u91CF\u8D26\u5355",
|
|
304
305
|
cancel: "\u8BA2\u9605\u53D6\u6D88",
|
|
305
306
|
manual: "\u4EBA\u5DE5\u8D26\u5355",
|
|
306
|
-
upcoming: "\u672A\u6765\u8D26\u5355"
|
|
307
|
+
upcoming: "\u672A\u6765\u8D26\u5355",
|
|
308
|
+
slashStake: "\u7F5A\u6CA1\u8D28\u62BC"
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
311
|
},
|
package/es/payment/form/index.js
CHANGED
|
@@ -3,15 +3,16 @@ import "react-international-phone/style.css";
|
|
|
3
3
|
import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
|
|
4
4
|
import Toast from "@arcblock/ux/lib/Toast";
|
|
5
5
|
import { LoadingButton } from "@mui/lab";
|
|
6
|
-
import { Divider, Fade, FormLabel, Stack, Typography } from "@mui/material";
|
|
6
|
+
import { Box, Divider, Fade, FormLabel, Stack, Typography } from "@mui/material";
|
|
7
7
|
import { useMemoizedFn, useSetState } from "ahooks";
|
|
8
8
|
import { PhoneNumberUtil } from "google-libphonenumber";
|
|
9
9
|
import pWaitFor from "p-wait-for";
|
|
10
|
-
import { useEffect, useMemo, useState } from "react";
|
|
10
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
11
11
|
import { Controller, useFormContext, useWatch } from "react-hook-form";
|
|
12
12
|
import { joinURL } from "ufo";
|
|
13
13
|
import { dispatch } from "use-bus";
|
|
14
14
|
import isEmail from "validator/es/lib/isEmail";
|
|
15
|
+
import { isEmpty } from "lodash";
|
|
15
16
|
import ConfirmDialog from "../../components/confirm.js";
|
|
16
17
|
import FormInput from "../../components/input.js";
|
|
17
18
|
import { usePaymentContext } from "../../contexts/payment.js";
|
|
@@ -29,6 +30,7 @@ import AddressForm from "./address.js";
|
|
|
29
30
|
import CurrencySelector from "./currency.js";
|
|
30
31
|
import PhoneInput from "./phone.js";
|
|
31
32
|
import StripeCheckout from "./stripe.js";
|
|
33
|
+
import { useMobile } from "../../hooks/mobile.js";
|
|
32
34
|
const phoneUtil = PhoneNumberUtil.getInstance();
|
|
33
35
|
const waitForCheckoutComplete = async (sessionId) => {
|
|
34
36
|
let result;
|
|
@@ -62,9 +64,17 @@ export default function PaymentForm({
|
|
|
62
64
|
action
|
|
63
65
|
}) {
|
|
64
66
|
const { t } = useLocaleContext();
|
|
67
|
+
const { isMobile } = useMobile();
|
|
65
68
|
const { session, connect, payable } = usePaymentContext();
|
|
66
69
|
const subscription = useSubscription("events");
|
|
67
|
-
const {
|
|
70
|
+
const {
|
|
71
|
+
control,
|
|
72
|
+
getValues,
|
|
73
|
+
setValue,
|
|
74
|
+
handleSubmit,
|
|
75
|
+
formState: { errors }
|
|
76
|
+
} = useFormContext();
|
|
77
|
+
const errorRef = useRef(null);
|
|
68
78
|
const quantityInventoryStatus = useMemo(() => {
|
|
69
79
|
let status = true;
|
|
70
80
|
for (const item of checkoutSession.line_items) {
|
|
@@ -163,6 +173,11 @@ export default function PaymentForm({
|
|
|
163
173
|
setState({ paying: false });
|
|
164
174
|
}
|
|
165
175
|
};
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
if (errorRef.current && !isEmpty(errors) && isMobile) {
|
|
178
|
+
errorRef.current.scrollIntoView({ behavior: "smooth" });
|
|
179
|
+
}
|
|
180
|
+
}, [errors, isMobile]);
|
|
166
181
|
const onUserLoggedIn = async () => {
|
|
167
182
|
const { data: profile } = await api.get("/api/customers/me?fallback=1");
|
|
168
183
|
if (profile) {
|
|
@@ -267,6 +282,9 @@ export default function PaymentForm({
|
|
|
267
282
|
setState({ submitting: false });
|
|
268
283
|
};
|
|
269
284
|
const onAction = () => {
|
|
285
|
+
if (errorRef.current && !isEmpty(errors) && isMobile) {
|
|
286
|
+
errorRef.current.scrollIntoView({ behavior: "smooth" });
|
|
287
|
+
}
|
|
270
288
|
if (session?.user) {
|
|
271
289
|
if (hasDidWallet(session.user)) {
|
|
272
290
|
handleSubmit(onFormSubmit, onFormError)();
|
|
@@ -343,68 +361,79 @@ export default function PaymentForm({
|
|
|
343
361
|
)
|
|
344
362
|
] }) }),
|
|
345
363
|
/* @__PURE__ */ jsx(Stack, { direction: "row", sx: { mb: 1 }, alignItems: "center", justifyContent: "space-between" }),
|
|
346
|
-
/* @__PURE__ */ jsxs(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
364
|
+
/* @__PURE__ */ jsxs(
|
|
365
|
+
Stack,
|
|
366
|
+
{
|
|
367
|
+
direction: "column",
|
|
368
|
+
className: "cko-payment-form",
|
|
369
|
+
id: "cko-payment-form",
|
|
370
|
+
spacing: 0,
|
|
371
|
+
ref: !isEmpty(errors) ? errorRef : void 0,
|
|
372
|
+
sx: { flex: 1, overflow: "auto" },
|
|
373
|
+
children: [
|
|
374
|
+
/* @__PURE__ */ jsx(FormLabel, { className: "base-label", children: t("payment.checkout.customer.name") }),
|
|
375
|
+
/* @__PURE__ */ jsx(
|
|
376
|
+
FormInput,
|
|
377
|
+
{
|
|
378
|
+
name: "customer_name",
|
|
379
|
+
variant: "outlined",
|
|
380
|
+
errorPosition: "right",
|
|
381
|
+
rules: {
|
|
382
|
+
required: t("payment.checkout.required")
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
),
|
|
386
|
+
/* @__PURE__ */ jsx(FormLabel, { className: "base-label", children: t("payment.checkout.customer.email") }),
|
|
387
|
+
/* @__PURE__ */ jsx(
|
|
388
|
+
FormInput,
|
|
389
|
+
{
|
|
390
|
+
name: "customer_email",
|
|
391
|
+
variant: "outlined",
|
|
392
|
+
errorPosition: "right",
|
|
393
|
+
rules: {
|
|
394
|
+
required: t("payment.checkout.required"),
|
|
395
|
+
validate: (x) => isEmail(x) ? true : t("payment.checkout.invalid")
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
checkoutSession.phone_number_collection?.enabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
400
|
+
/* @__PURE__ */ jsx(FormLabel, { className: "base-label", children: t("payment.checkout.customer.phone") }),
|
|
401
|
+
/* @__PURE__ */ jsx(
|
|
402
|
+
PhoneInput,
|
|
403
|
+
{
|
|
404
|
+
name: "customer_phone",
|
|
405
|
+
variant: "outlined",
|
|
406
|
+
errorPosition: "right",
|
|
407
|
+
placeholder: "Phone number",
|
|
408
|
+
rules: {
|
|
409
|
+
required: t("payment.checkout.required"),
|
|
410
|
+
validate: (x) => {
|
|
411
|
+
try {
|
|
412
|
+
const parsed = phoneUtil.parseAndKeepRawInput(x);
|
|
413
|
+
return phoneUtil.isValidNumber(parsed) ? true : t("payment.checkout.invalid");
|
|
414
|
+
} catch {
|
|
415
|
+
return t("payment.checkout.invalid");
|
|
416
|
+
}
|
|
417
|
+
}
|
|
389
418
|
}
|
|
390
419
|
}
|
|
420
|
+
)
|
|
421
|
+
] }),
|
|
422
|
+
/* @__PURE__ */ jsx(
|
|
423
|
+
AddressForm,
|
|
424
|
+
{
|
|
425
|
+
mode: checkoutSession.billing_address_collection,
|
|
426
|
+
stripe: method?.type === "stripe",
|
|
427
|
+
sx: { marginTop: "0 !important" }
|
|
391
428
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
AddressForm,
|
|
397
|
-
{
|
|
398
|
-
mode: checkoutSession.billing_address_collection,
|
|
399
|
-
stripe: method?.type === "stripe",
|
|
400
|
-
sx: { marginTop: "0 !important" }
|
|
401
|
-
}
|
|
402
|
-
)
|
|
403
|
-
] })
|
|
429
|
+
)
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
)
|
|
404
433
|
] }) }),
|
|
405
434
|
/* @__PURE__ */ jsx(Divider, { sx: { mt: 2.5, mb: 2.5 } }),
|
|
406
435
|
/* @__PURE__ */ jsx(Fade, { in: true, children: /* @__PURE__ */ jsxs(Stack, { className: "cko-payment-submit", children: [
|
|
407
|
-
/* @__PURE__ */ jsx(
|
|
436
|
+
/* @__PURE__ */ jsx(Box, { className: "cko-payment-submit-btn", children: /* @__PURE__ */ jsx(
|
|
408
437
|
LoadingButton,
|
|
409
438
|
{
|
|
410
439
|
variant: "contained",
|
|
@@ -417,7 +446,7 @@ export default function PaymentForm({
|
|
|
417
446
|
loading: state.submitting || state.paying,
|
|
418
447
|
children: state.submitting || state.paying ? t("payment.checkout.processing") : buttonText
|
|
419
448
|
}
|
|
420
|
-
),
|
|
449
|
+
) }),
|
|
421
450
|
["subscription", "setup"].includes(checkoutSession.mode) && /* @__PURE__ */ jsx(Typography, { sx: { mt: 2.5, color: "text.lighter", fontSize: "0.9rem", lineHeight: "1.1rem" }, children: t("payment.checkout.confirm", { payee }) })
|
|
422
451
|
] }) }),
|
|
423
452
|
state.customerLimited && /* @__PURE__ */ jsx(
|
package/es/payment/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { useEffect, useState } from "react";
|
|
|
11
11
|
import { FormProvider, useForm, useWatch } from "react-hook-form";
|
|
12
12
|
import { usePaymentContext } from "../contexts/payment.js";
|
|
13
13
|
import api from "../libs/api.js";
|
|
14
|
-
import { findCurrency, formatError, getStatementDescriptor, isValidCountry } from "../libs/util.js";
|
|
14
|
+
import { findCurrency, formatError, getStatementDescriptor, isMobileSafari, isValidCountry } from "../libs/util.js";
|
|
15
15
|
import PaymentError from "./error.js";
|
|
16
16
|
import CheckoutFooter from "./footer.js";
|
|
17
17
|
import PaymentForm from "./form/index.js";
|
|
@@ -66,6 +66,25 @@ function PaymentInner({
|
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (!isMobileSafari()) {
|
|
71
|
+
return () => {
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
let scrollTop = 0;
|
|
75
|
+
const focusinHandler = () => {
|
|
76
|
+
scrollTop = window.scrollY;
|
|
77
|
+
};
|
|
78
|
+
const focusoutHandler = () => {
|
|
79
|
+
window.scrollTo(0, scrollTop);
|
|
80
|
+
};
|
|
81
|
+
document.body.addEventListener("focusin", focusinHandler);
|
|
82
|
+
document.body.addEventListener("focusout", focusoutHandler);
|
|
83
|
+
return () => {
|
|
84
|
+
document.body.removeEventListener("focusin", focusinHandler);
|
|
85
|
+
document.body.removeEventListener("focusout", focusoutHandler);
|
|
86
|
+
};
|
|
87
|
+
}, []);
|
|
69
88
|
const currencyId = useWatch({ control: methods.control, name: "payment_currency", defaultValue: defaultCurrencyId });
|
|
70
89
|
const currency = findCurrency(paymentMethods, currencyId) || settings.baseCurrency;
|
|
71
90
|
const method = paymentMethods.find((x) => x.id === currency.payment_method_id);
|
|
@@ -221,7 +240,9 @@ export default function Payment({
|
|
|
221
240
|
const { t } = useLocaleContext();
|
|
222
241
|
const { refresh, livemode, setLivemode } = usePaymentContext();
|
|
223
242
|
const [delay, setDelay] = useState(false);
|
|
243
|
+
const { isMobile } = useMobile();
|
|
224
244
|
const hideSummaryCard = mode.endsWith("-minimal") || !showCheckoutSummary;
|
|
245
|
+
const isMobileSafariEnv = isMobileSafari();
|
|
225
246
|
useEffect(() => {
|
|
226
247
|
setTimeout(() => {
|
|
227
248
|
setDelay(true);
|
|
@@ -291,7 +312,10 @@ export default function Payment({
|
|
|
291
312
|
{
|
|
292
313
|
display: "flex",
|
|
293
314
|
flexDirection: "column",
|
|
294
|
-
sx: {
|
|
315
|
+
sx: {
|
|
316
|
+
height: mode === "standalone" ? "100vh" : "auto",
|
|
317
|
+
overflow: isMobileSafariEnv ? "visible" : "hidden"
|
|
318
|
+
},
|
|
295
319
|
children: [
|
|
296
320
|
mode === "standalone" ? /* @__PURE__ */ jsx(
|
|
297
321
|
Header,
|
|
@@ -306,17 +330,58 @@ export default function Payment({
|
|
|
306
330
|
sx: { borderBottom: "1px solid var(--stroke-border-base, #EFF1F5)" }
|
|
307
331
|
}
|
|
308
332
|
) : null,
|
|
309
|
-
/* @__PURE__ */ jsxs(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
333
|
+
/* @__PURE__ */ jsxs(
|
|
334
|
+
Root,
|
|
335
|
+
{
|
|
336
|
+
mode,
|
|
337
|
+
sx: {
|
|
338
|
+
flex: 1,
|
|
339
|
+
overflow: {
|
|
340
|
+
xs: isMobileSafariEnv ? "visible" : "auto",
|
|
341
|
+
md: "hidden"
|
|
342
|
+
},
|
|
343
|
+
...isMobile && mode === "standalone" ? {
|
|
344
|
+
".cko-payment-submit-btn": {
|
|
345
|
+
position: "fixed",
|
|
346
|
+
bottom: 20,
|
|
347
|
+
left: 0,
|
|
348
|
+
right: 0,
|
|
349
|
+
zIndex: 999,
|
|
350
|
+
background: "#fff",
|
|
351
|
+
padding: "10px",
|
|
352
|
+
textAlign: "center",
|
|
353
|
+
button: {
|
|
354
|
+
color: "#fff",
|
|
355
|
+
maxWidth: 542
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
".cko-footer": {
|
|
359
|
+
position: "fixed",
|
|
360
|
+
bottom: 0,
|
|
361
|
+
left: 0,
|
|
362
|
+
right: 0,
|
|
363
|
+
zIndex: 999,
|
|
364
|
+
background: "#fff",
|
|
365
|
+
marginBottom: 0
|
|
366
|
+
},
|
|
367
|
+
".cko-payment": {
|
|
368
|
+
paddingBottom: "100px"
|
|
369
|
+
}
|
|
370
|
+
} : {}
|
|
371
|
+
},
|
|
372
|
+
children: [
|
|
373
|
+
goBack && /* @__PURE__ */ jsx(
|
|
374
|
+
ArrowBackOutlined,
|
|
375
|
+
{
|
|
376
|
+
sx: { mr: 0.5, color: "text.secondary", alignSelf: "flex-start", margin: "16px 0", cursor: "pointer" },
|
|
377
|
+
onClick: goBack,
|
|
378
|
+
fontSize: "medium"
|
|
379
|
+
}
|
|
380
|
+
),
|
|
381
|
+
/* @__PURE__ */ jsx(Stack, { className: "cko-container", sx: { gap: { sm: mode === "standalone" ? 0 : mode === "inline" ? 4 : 8 } }, children: renderContent() })
|
|
382
|
+
]
|
|
383
|
+
}
|
|
384
|
+
)
|
|
320
385
|
]
|
|
321
386
|
}
|
|
322
387
|
);
|
|
@@ -461,7 +526,6 @@ export const Root = styled(Box)`
|
|
|
461
526
|
}
|
|
462
527
|
|
|
463
528
|
@media (max-width: ${({ theme }) => theme.breakpoints.values.md}px) {
|
|
464
|
-
background: ${(props) => props.mode === "standalone" ? "var(--backgrounds-bg-subtle, #F9FAFB)" : "transparent"};
|
|
465
529
|
padding-top: 0;
|
|
466
530
|
overflow: auto;
|
|
467
531
|
&:before {
|
|
@@ -470,7 +534,8 @@ export const Root = styled(Box)`
|
|
|
470
534
|
.cko-container {
|
|
471
535
|
flex-direction: column;
|
|
472
536
|
align-items: center;
|
|
473
|
-
|
|
537
|
+
justify-content: flex-start;
|
|
538
|
+
gap: 0;
|
|
474
539
|
overflow: visible;
|
|
475
540
|
min-width: 200px;
|
|
476
541
|
}
|
|
@@ -483,6 +548,7 @@ export const Root = styled(Box)`
|
|
|
483
548
|
width: 100%;
|
|
484
549
|
height: fit-content;
|
|
485
550
|
flex: none;
|
|
551
|
+
border-top: 1px solid var(--stroke-border-base, #eff1f5);
|
|
486
552
|
&:before {
|
|
487
553
|
display: none;
|
|
488
554
|
}
|
package/es/payment/summary.js
CHANGED
|
@@ -277,30 +277,14 @@ export default function PaymentSummary({
|
|
|
277
277
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 1, children: [
|
|
278
278
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
|
|
279
279
|
/* @__PURE__ */ jsx(Typography, { sx: { color: "text.secondary" }, children: t("payment.checkout.paymentRequired") }),
|
|
280
|
-
/* @__PURE__ */ jsx(
|
|
281
|
-
Tooltip,
|
|
282
|
-
{
|
|
283
|
-
title: /* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.stakingConfirm") }),
|
|
284
|
-
placement: "top",
|
|
285
|
-
sx: { maxWidth: "150px" },
|
|
286
|
-
children: /* @__PURE__ */ jsx(HelpOutline, { fontSize: "small", sx: { color: "text.lighter" } })
|
|
287
|
-
}
|
|
288
|
-
)
|
|
280
|
+
/* @__PURE__ */ jsx(Tooltip, { title: t("payment.checkout.stakingConfirm"), placement: "top", sx: { maxWidth: "150px" }, children: /* @__PURE__ */ jsx(HelpOutline, { fontSize: "small", sx: { color: "text.lighter" } }) })
|
|
289
281
|
] }),
|
|
290
282
|
/* @__PURE__ */ jsx(Typography, { children: headlines.amount })
|
|
291
283
|
] }),
|
|
292
284
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", spacing: 1, children: [
|
|
293
285
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", spacing: 0.5, children: [
|
|
294
286
|
/* @__PURE__ */ jsx(Typography, { sx: { color: "text.secondary" }, children: t("payment.checkout.staking.title") }),
|
|
295
|
-
/* @__PURE__ */ jsx(
|
|
296
|
-
Tooltip,
|
|
297
|
-
{
|
|
298
|
-
title: /* @__PURE__ */ jsx(Typography, { children: t("payment.checkout.staking.tooltip") }),
|
|
299
|
-
placement: "top",
|
|
300
|
-
sx: { maxWidth: "150px" },
|
|
301
|
-
children: /* @__PURE__ */ jsx(HelpOutline, { fontSize: "small", sx: { color: "text.lighter" } })
|
|
302
|
-
}
|
|
303
|
-
)
|
|
287
|
+
/* @__PURE__ */ jsx(Tooltip, { title: t("payment.checkout.staking.tooltip"), placement: "top", sx: { maxWidth: "150px" }, children: /* @__PURE__ */ jsx(HelpOutline, { fontSize: "small", sx: { color: "text.lighter" } }) })
|
|
304
288
|
] }),
|
|
305
289
|
/* @__PURE__ */ jsxs(Typography, { children: [
|
|
306
290
|
formatAmount(staking, currency.decimal),
|