@akinon/next 1.42.0 → 1.43.0-rc.0
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/CHANGELOG.md +33 -0
- package/api/client.ts +33 -9
- package/assets/styles/index.css +49 -0
- package/assets/styles/index.css.map +1 -0
- package/assets/styles/index.scss +50 -26
- package/components/input.tsx +21 -7
- package/components/link.tsx +17 -13
- package/components/pagination.tsx +1 -2
- package/components/price.tsx +11 -4
- package/components/selected-payment-option-view.tsx +26 -38
- package/data/client/account.ts +10 -9
- package/data/client/api.ts +1 -1
- package/data/client/checkout.ts +26 -3
- package/data/server/category.ts +2 -2
- package/data/server/list.ts +2 -2
- package/data/server/product.ts +15 -13
- package/data/server/special-page.ts +2 -2
- package/data/urls.ts +2 -0
- package/hocs/server/with-segment-defaults.tsx +2 -2
- package/hooks/index.ts +2 -1
- package/hooks/use-message-listener.ts +24 -0
- package/hooks/use-payment-options.ts +2 -1
- package/lib/cache-handler.mjs +33 -0
- package/lib/cache.ts +18 -6
- package/middlewares/default.ts +37 -2
- package/middlewares/pretty-url.ts +4 -0
- package/middlewares/url-redirection.ts +4 -0
- package/package.json +5 -4
- package/plugins.d.ts +1 -0
- package/redux/middlewares/checkout.ts +40 -9
- package/redux/reducers/checkout.ts +9 -3
- package/redux/reducers/config.ts +2 -0
- package/routes/pretty-url.tsx +194 -0
- package/types/commerce/account.ts +1 -0
- package/types/commerce/address.ts +1 -1
- package/types/commerce/checkout.ts +18 -0
- package/types/commerce/misc.ts +2 -0
- package/types/commerce/order.ts +12 -0
- package/types/index.ts +28 -2
- package/utils/app-fetch.ts +1 -1
- package/utils/generate-commerce-search-params.ts +6 -2
- package/utils/index.ts +27 -6
- package/utils/redirection-iframe.ts +85 -0
- package/utils/server-translation.ts +5 -1
- package/with-pz-config.js +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
+
## 1.43.0-rc.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 90282b5: ZERO-2729: Audit packages for yarn and npm and also update app-template
|
|
8
|
+
- 572d2e8: ZERO-2667: Add iframe support for redirection payment methods
|
|
9
|
+
- a4c8d6a: ZERO-2663: Fix the image url for gif and svgs and return them without options
|
|
10
|
+
- fda5b92: ZERO-2725: fix invalid import
|
|
11
|
+
- 2d9b2b2: ZERO-2816: Add segment to headers
|
|
12
|
+
- c53ea3e: ZERO-2609: Reset additional form fields when selectedFormType is not company
|
|
13
|
+
- 8d9ac9a: ZERO-2794: Add field to order type
|
|
14
|
+
- e9541a1: ZERO-2816: Add headers to url
|
|
15
|
+
- c53ef7b: ZERO-2668: The Link component has been updated to improve the logic for handling href values. Previously, if the href was not a string or started with 'http', it would return the href as is. Now, if the href is not provided, it will default to '#' to prevent any potential errors. Additionally, if the href is a string and does not start with 'http', it will be formatted with the locale and pathname, based on the localeUrlStrategy and defaultLocaleValue. This ensures that the correct href is generated based on the localization settings.
|
|
16
|
+
- 0d3a913: ZERO-2725: Update decimal scale in Price component
|
|
17
|
+
- 1448a96: ZERO-2612: add errors type in CheckoutState
|
|
18
|
+
- d3474c6: ZERO-2655: Add data source shipping option
|
|
19
|
+
- 75080fd: ZERO-2630: Add max limit to postcode area
|
|
20
|
+
- 91265bb: ZERO-2551: Improve pretty url and caching performance
|
|
21
|
+
- bbe18b9: ZERO-2575: Fix build error
|
|
22
|
+
- d409996: ZERO-2781: Refactor buildClientRequestUrl function to support caching and options
|
|
23
|
+
- 94b6928: ZERO-2551: Add cache handler check in url-redirection middleware
|
|
24
|
+
- 98bb8dc: ZERO-2706: Cache getTranlations method
|
|
25
|
+
- 46b7aad: ZERO-2775: Add condition and logger for menuitemmodel data
|
|
26
|
+
- dcc8a15: ZERO-2694: added build step to RC branch pipeline
|
|
27
|
+
- fad2768: ZERO-2739: add gpay to payment plugin map
|
|
28
|
+
- dff0d59: ZERO-2659: add formData support to proxy api requests
|
|
29
|
+
- beb499e: ZERO-2551: Add new tsconfig paths
|
|
30
|
+
- 146ea39: ZERO-2774: Update imports
|
|
31
|
+
- c47be30: ZERO-2744: Update Order and OrderItem types
|
|
32
|
+
- e9a46ac: ZERO-2738: add CVC input to registered cards in Masterpass
|
|
33
|
+
- f046f8e: ZERO-2575: update version for react-number-format
|
|
34
|
+
- 86d2531: ZERO-2693: resolve dependency collision warning for eslint-config-next
|
|
35
|
+
|
|
3
36
|
## 1.42.0
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
package/api/client.ts
CHANGED
|
@@ -4,6 +4,7 @@ import settings from 'settings';
|
|
|
4
4
|
import logger from '../utils/log';
|
|
5
5
|
import formatCookieString from '../utils/format-cookie-string';
|
|
6
6
|
import cookieParser from 'set-cookie-parser';
|
|
7
|
+
import { cookies } from 'next/headers';
|
|
7
8
|
|
|
8
9
|
interface RouteParams {
|
|
9
10
|
params: {
|
|
@@ -74,16 +75,31 @@ async function proxyRequest(...args) {
|
|
|
74
75
|
}
|
|
75
76
|
} as RequestInit;
|
|
76
77
|
|
|
78
|
+
const nextCookies = cookies();
|
|
79
|
+
const segment = nextCookies.get('pz-segment')?.value;
|
|
80
|
+
const currency = nextCookies.get('pz-external-currency')?.value;
|
|
81
|
+
|
|
82
|
+
if (segment) {
|
|
83
|
+
fetchOptions.headers['X-Segment-Id'] = segment;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (currency) {
|
|
87
|
+
fetchOptions.headers = Object.assign({}, fetchOptions.headers, {
|
|
88
|
+
'x-currency': currency
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
77
92
|
if (options.contentType) {
|
|
78
93
|
fetchOptions.headers['Content-Type'] = options.contentType;
|
|
79
94
|
}
|
|
80
95
|
|
|
96
|
+
const isMultipartFormData = req.headers.get('content-type')?.includes('multipart/form-data;');
|
|
97
|
+
|
|
81
98
|
if (req.method !== 'GET') {
|
|
82
|
-
|
|
83
|
-
let body = {};
|
|
99
|
+
let body: Record<string, any> | FormData = {};
|
|
84
100
|
|
|
85
101
|
try {
|
|
86
|
-
body = await req.json();
|
|
102
|
+
body = isMultipartFormData ? await req.formData() : await req.json();
|
|
87
103
|
} catch (error) {
|
|
88
104
|
logger.error(
|
|
89
105
|
`Client Proxy Request - Error while parsing request body to JSON`,
|
|
@@ -94,13 +110,21 @@ async function proxyRequest(...args) {
|
|
|
94
110
|
);
|
|
95
111
|
}
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
if (isMultipartFormData) {
|
|
114
|
+
fetchOptions.body = body as FormData;
|
|
115
|
+
} else {
|
|
116
|
+
const formData = new FormData();
|
|
117
|
+
|
|
118
|
+
Object.keys(body ?? {}).forEach((key) => {
|
|
119
|
+
if (body[key]) {
|
|
120
|
+
formData.append(key, body[key]);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
102
123
|
|
|
103
|
-
|
|
124
|
+
fetchOptions.body = !options.useFormData
|
|
125
|
+
? JSON.stringify(body)
|
|
126
|
+
: formData;
|
|
127
|
+
}
|
|
104
128
|
}
|
|
105
129
|
|
|
106
130
|
let url = `${commerceUrl}/${slug.replace(/,/g, '/')}`;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.checkout-payment-iframe-wrapper {
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
border: none;
|
|
8
|
+
z-index: 1000;
|
|
9
|
+
background-color: white;
|
|
10
|
+
}
|
|
11
|
+
.checkout-payment-iframe-wrapper iframe {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
background-color: white;
|
|
16
|
+
}
|
|
17
|
+
.checkout-payment-iframe-wrapper .close-button {
|
|
18
|
+
position: fixed;
|
|
19
|
+
top: 16px;
|
|
20
|
+
right: 16px;
|
|
21
|
+
width: 32px;
|
|
22
|
+
height: 32px;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
z-index: 1001;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.checkout-payment-redirection-iframe-wrapper {
|
|
30
|
+
width: 100%;
|
|
31
|
+
position: relative;
|
|
32
|
+
}
|
|
33
|
+
.checkout-payment-redirection-iframe-wrapper iframe {
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: 100%;
|
|
36
|
+
border: none;
|
|
37
|
+
background-color: white;
|
|
38
|
+
}
|
|
39
|
+
.checkout-payment-redirection-iframe-wrapper .close-button {
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 16px;
|
|
42
|
+
right: 16px;
|
|
43
|
+
width: 32px;
|
|
44
|
+
height: 32px;
|
|
45
|
+
display: flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
z-index: 1001;
|
|
49
|
+
}/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["index.scss","index.css"],"names":[],"mappings":"AAAA;EACE,eAAA;EACA,MAAA;EACA,OAAA;EACA,WAAA;EACA,YAAA;EACA,YAAA;EACA,aAAA;EACA,uBAAA;ACCF;ADCE;EACE,WAAA;EACA,YAAA;EACA,YAAA;EACA,uBAAA;ACCJ;ADEE;EACE,eAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,aAAA;ACAJ;;ADIA;EACE,WAAA;EACA,kBAAA;ACDF;ADGE;EACE,WAAA;EACA,YAAA;EACA,YAAA;EACA,uBAAA;ACDJ;ADIE;EACE,kBAAA;EACA,SAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,aAAA;ACFJ","file":"index.css"}
|
package/assets/styles/index.scss
CHANGED
|
@@ -1,29 +1,53 @@
|
|
|
1
1
|
.checkout-payment-iframe-wrapper {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
border: none;
|
|
8
|
+
z-index: 1000;
|
|
9
|
+
background-color: white;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
iframe {
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
background-color: white;
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
18
|
+
.close-button {
|
|
19
|
+
position: fixed;
|
|
20
|
+
top: 16px;
|
|
21
|
+
right: 16px;
|
|
22
|
+
width: 32px;
|
|
23
|
+
height: 32px;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
justify-content: center;
|
|
27
|
+
z-index: 1001;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.checkout-payment-redirection-iframe-wrapper {
|
|
32
|
+
width: 100%;
|
|
33
|
+
position: relative;
|
|
34
|
+
|
|
35
|
+
iframe {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
border: none;
|
|
39
|
+
background-color: white;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.close-button {
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 16px;
|
|
45
|
+
right: 16px;
|
|
46
|
+
width: 32px;
|
|
47
|
+
height: 32px;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
z-index: 1001;
|
|
52
|
+
}
|
|
53
|
+
}
|
package/components/input.tsx
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import { forwardRef, FocusEvent, useState } from 'react';
|
|
2
|
+
import { forwardRef, FocusEvent, useState, Ref } from 'react';
|
|
3
3
|
import { Controller } from 'react-hook-form';
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
import { PatternFormat, PatternFormatProps } from 'react-number-format';
|
|
5
7
|
import { InputProps } from '../types';
|
|
6
8
|
import { twMerge } from 'tailwind-merge';
|
|
7
9
|
|
|
10
|
+
const PatternFormatWithRef = forwardRef(
|
|
11
|
+
(props: PatternFormatProps, ref: Ref<HTMLInputElement>) => {
|
|
12
|
+
return <PatternFormat {...props} getInputRef={ref} />;
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
PatternFormatWithRef.displayName = 'PatternFormatWithRef';
|
|
16
|
+
|
|
8
17
|
export const Input = forwardRef<
|
|
9
18
|
HTMLInputElement,
|
|
10
19
|
InputProps &
|
|
11
20
|
Pick<
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
>
|
|
21
|
+
PatternFormatProps,
|
|
22
|
+
'mask' | 'allowEmptyFormatting' | 'onValueChange'
|
|
23
|
+
> & {
|
|
24
|
+
format?: string;
|
|
25
|
+
defaultValue?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
}
|
|
15
28
|
>((props, ref) => {
|
|
16
29
|
const [focused, setFocused] = useState(false);
|
|
17
30
|
const [hasValue, setHasValue] = useState(false);
|
|
@@ -37,6 +50,7 @@ export const Input = forwardRef<
|
|
|
37
50
|
),
|
|
38
51
|
props.className
|
|
39
52
|
);
|
|
53
|
+
|
|
40
54
|
const inputProps: any = {
|
|
41
55
|
id,
|
|
42
56
|
ref,
|
|
@@ -79,14 +93,14 @@ export const Input = forwardRef<
|
|
|
79
93
|
<Controller
|
|
80
94
|
name={props.name ?? ''}
|
|
81
95
|
control={props.control}
|
|
82
|
-
defaultValue={false}
|
|
83
96
|
render={({ field }) => (
|
|
84
|
-
<
|
|
97
|
+
<PatternFormatWithRef
|
|
85
98
|
format={format}
|
|
86
99
|
mask={mask ?? ''}
|
|
87
100
|
{...rest}
|
|
88
101
|
{...field}
|
|
89
102
|
{...inputProps}
|
|
103
|
+
type={props.type as 'text' | 'password' | 'tel'}
|
|
90
104
|
/>
|
|
91
105
|
)}
|
|
92
106
|
/>
|
package/components/link.tsx
CHANGED
|
@@ -10,28 +10,32 @@ type LinkProps = Omit<
|
|
|
10
10
|
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
11
11
|
keyof NextLinkProps
|
|
12
12
|
> &
|
|
13
|
-
NextLinkProps
|
|
13
|
+
NextLinkProps & {
|
|
14
|
+
href: string;
|
|
15
|
+
};
|
|
14
16
|
|
|
15
17
|
export const Link = ({ children, href, ...rest }: LinkProps) => {
|
|
16
18
|
const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
|
|
17
19
|
const formattedHref = useMemo(() => {
|
|
18
|
-
if (
|
|
19
|
-
return
|
|
20
|
+
if (!href) {
|
|
21
|
+
return '#';
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
if (typeof href === 'string' && !href.startsWith('http')) {
|
|
25
|
+
const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
|
|
26
|
+
const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
|
|
29
|
+
return hrefWithLocale;
|
|
30
|
+
} else if (
|
|
31
|
+
localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
|
|
32
|
+
locale !== defaultLocaleValue
|
|
33
|
+
) {
|
|
34
|
+
return hrefWithLocale;
|
|
35
|
+
}
|
|
32
36
|
}
|
|
33
37
|
|
|
34
|
-
return href
|
|
38
|
+
return href;
|
|
35
39
|
}, [href, defaultLocaleValue, locale, localeUrlStrategy]);
|
|
36
40
|
|
|
37
41
|
return (
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { MouseEvent, useCallback, useEffect, useState } from 'react';
|
|
4
|
-
import { PaginationProps } from '
|
|
4
|
+
import { PaginationProps } from '../types';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import clsx from 'clsx';
|
|
7
|
-
|
|
8
7
|
import usePagination from '@akinon/next/hooks/use-pagination';
|
|
9
8
|
import { useLocalization } from '@akinon/next/hooks';
|
|
10
9
|
import { useRouter } from '@akinon/next/hooks';
|
package/components/price.tsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { NumericFormat, NumericFormatProps } from 'react-number-format';
|
|
3
5
|
import { getCurrency } from '@akinon/next/utils';
|
|
4
6
|
|
|
5
7
|
import { useLocalization } from '@akinon/next/hooks';
|
|
6
8
|
import { PriceProps } from '../types';
|
|
9
|
+
import Settings from 'settings';
|
|
7
10
|
|
|
8
|
-
export const Price = (props:
|
|
11
|
+
export const Price = (props: NumericFormatProps & PriceProps) => {
|
|
9
12
|
const {
|
|
10
13
|
value,
|
|
11
14
|
currencyCode,
|
|
@@ -27,6 +30,10 @@ export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
|
27
30
|
// TODO: This is very bad practice. It broke decimalScale.
|
|
28
31
|
const _value = value?.toString().replace('.', ',');
|
|
29
32
|
|
|
33
|
+
const currentCurrencyDecimalScale = Settings.localization.currencies.find(
|
|
34
|
+
(currency) => currency.code === currencyCode_
|
|
35
|
+
).decimalScale;
|
|
36
|
+
|
|
30
37
|
const currency = useMemo(
|
|
31
38
|
() =>
|
|
32
39
|
getCurrency({
|
|
@@ -39,14 +46,14 @@ export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
|
39
46
|
);
|
|
40
47
|
|
|
41
48
|
return (
|
|
42
|
-
<
|
|
49
|
+
<NumericFormat
|
|
43
50
|
value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
|
|
44
51
|
{...{
|
|
45
52
|
[useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
|
|
46
53
|
}}
|
|
47
54
|
displayType={displayType}
|
|
48
55
|
thousandSeparator={thousandSeparator}
|
|
49
|
-
decimalScale={decimalScale}
|
|
56
|
+
decimalScale={currentCurrencyDecimalScale ?? decimalScale}
|
|
50
57
|
decimalSeparator={decimalSeparator}
|
|
51
58
|
fixedDecimalScale={fixedDecimalScale}
|
|
52
59
|
{...rest}
|
|
@@ -6,6 +6,21 @@ import dynamic from 'next/dynamic';
|
|
|
6
6
|
import { PaymentOptionViews } from 'views/checkout/steps/payment';
|
|
7
7
|
import { useMemo } from 'react';
|
|
8
8
|
|
|
9
|
+
const fallbackView = () => <div />;
|
|
10
|
+
|
|
11
|
+
const paymentTypeToView = {
|
|
12
|
+
bkm_express: 'bkm',
|
|
13
|
+
credit_card: 'credit-card',
|
|
14
|
+
credit_payment: 'credit-payment',
|
|
15
|
+
funds_transfer: 'funds-transfer',
|
|
16
|
+
gpay: 'gpay',
|
|
17
|
+
loyalty_money: 'loyalty',
|
|
18
|
+
masterpass: 'credit-card',
|
|
19
|
+
pay_on_delivery: 'pay-on-delivery',
|
|
20
|
+
redirection: 'redirection'
|
|
21
|
+
// Add other mappings as needed
|
|
22
|
+
};
|
|
23
|
+
|
|
9
24
|
export default function SelectedPaymentOptionView() {
|
|
10
25
|
const { payment_option } = useAppSelector(
|
|
11
26
|
(state: RootState) => state.checkout.preOrder
|
|
@@ -14,7 +29,7 @@ export default function SelectedPaymentOptionView() {
|
|
|
14
29
|
const Component = useMemo(
|
|
15
30
|
() =>
|
|
16
31
|
dynamic(
|
|
17
|
-
() => {
|
|
32
|
+
async () => {
|
|
18
33
|
const customOption = PaymentOptionViews.find(
|
|
19
34
|
(opt) => opt.slug === payment_option.slug
|
|
20
35
|
);
|
|
@@ -29,46 +44,19 @@ export default function SelectedPaymentOptionView() {
|
|
|
29
44
|
});
|
|
30
45
|
}
|
|
31
46
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`views/checkout/steps/payment/options/credit-card`
|
|
38
|
-
);
|
|
39
|
-
} else if (payment_option.payment_type === 'funds_transfer') {
|
|
40
|
-
promise = import(
|
|
41
|
-
`views/checkout/steps/payment/options/funds-transfer`
|
|
42
|
-
);
|
|
43
|
-
} else if (payment_option.payment_type === 'redirection') {
|
|
44
|
-
promise = import(
|
|
45
|
-
`views/checkout/steps/payment/options/redirection`
|
|
46
|
-
);
|
|
47
|
-
} else if (payment_option.payment_type === 'pay_on_delivery') {
|
|
48
|
-
promise = import(
|
|
49
|
-
`views/checkout/steps/payment/options/pay-on-delivery`
|
|
50
|
-
);
|
|
51
|
-
} else if (payment_option.payment_type === 'loyalty_money') {
|
|
52
|
-
promise = import(`views/checkout/steps/payment/options/loyalty`);
|
|
53
|
-
} else if (payment_option.payment_type === 'masterpass') {
|
|
54
|
-
promise = import(
|
|
55
|
-
`views/checkout/steps/payment/options/credit-card`
|
|
47
|
+
const view = paymentTypeToView[payment_option.payment_type];
|
|
48
|
+
if (view) {
|
|
49
|
+
try {
|
|
50
|
+
const mod = await import(
|
|
51
|
+
`views/checkout/steps/payment/options/${view}`
|
|
56
52
|
);
|
|
53
|
+
return mod.default || fallbackView;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return fallbackView;
|
|
57
56
|
}
|
|
58
|
-
|
|
59
|
-
// promise = import(`views/checkout/steps/payment/options/credit-payment`);
|
|
60
|
-
// }
|
|
61
|
-
// else if (payment_option.payment_type === 'gpay') {
|
|
62
|
-
// promise = import(`views/checkout/steps/payment/options/gpay`);
|
|
63
|
-
// }
|
|
64
|
-
// else if (payment_option.payment_type === 'bkm_express') {
|
|
65
|
-
// promise = import(`views/checkout/steps/payment/options/bkm`);
|
|
66
|
-
// }
|
|
67
|
-
} catch (error) {}
|
|
57
|
+
}
|
|
68
58
|
|
|
69
|
-
return
|
|
70
|
-
? promise.then((mod) => mod.default).catch(() => () => null)
|
|
71
|
-
: new Promise<any>((resolve) => resolve(() => null));
|
|
59
|
+
return fallbackView;
|
|
72
60
|
},
|
|
73
61
|
{ ssr: false }
|
|
74
62
|
),
|
package/data/client/account.ts
CHANGED
|
@@ -123,15 +123,16 @@ const accountApi = api.injectEndpoints({
|
|
|
123
123
|
query: ({ page, status, limit }) =>
|
|
124
124
|
buildClientRequestUrl(account.getQuotations(page, status, limit))
|
|
125
125
|
}),
|
|
126
|
-
sendContact: builder.mutation<void,
|
|
127
|
-
query: (body) =>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
126
|
+
sendContact: builder.mutation<void, FormData>({
|
|
127
|
+
query: (body) => {
|
|
128
|
+
return {
|
|
129
|
+
url: buildClientRequestUrl(account.sendContact, {
|
|
130
|
+
useFormData: true
|
|
131
|
+
}),
|
|
132
|
+
method: 'POST',
|
|
133
|
+
body
|
|
134
|
+
};
|
|
135
|
+
}
|
|
135
136
|
}),
|
|
136
137
|
cancelOrder: builder.mutation<void, AccountOrderCancellation>({
|
|
137
138
|
query: ({ id, ...body }) => ({
|
package/data/client/api.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@reduxjs/toolkit/query/react';
|
|
10
10
|
import settings from 'settings';
|
|
11
11
|
import { getCookie } from '../../utils';
|
|
12
|
-
import { RootState } from '
|
|
12
|
+
import { RootState } from 'redux/store';
|
|
13
13
|
|
|
14
14
|
interface CustomBaseQueryApi extends BaseQueryApi {
|
|
15
15
|
getState: () => RootState;
|
package/data/client/checkout.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
setBankAccounts,
|
|
3
|
+
setCardType,
|
|
3
4
|
setInstallmentOptions,
|
|
4
5
|
setPaymentStepBusy,
|
|
5
6
|
setSelectedBankAccountPk,
|
|
6
7
|
setSelectedCreditPaymentPk,
|
|
7
|
-
setShippingStepBusy
|
|
8
|
-
setCardType
|
|
8
|
+
setShippingStepBusy
|
|
9
9
|
} from '../../redux/reducers/checkout';
|
|
10
10
|
import {
|
|
11
11
|
CheckoutContext,
|
|
@@ -20,6 +20,7 @@ import { AppDispatch, AppStore, store } from 'redux/store';
|
|
|
20
20
|
import settings from 'settings';
|
|
21
21
|
import { showMobile3dIframe } from '../../utils/mobile-3d-iframe';
|
|
22
22
|
import {
|
|
23
|
+
setCvcRequired,
|
|
23
24
|
setError,
|
|
24
25
|
setOtpModalVisible
|
|
25
26
|
} from '@akinon/pz-masterpass/src/redux/reducer';
|
|
@@ -113,7 +114,8 @@ const completeMasterpassPayment = async (
|
|
|
113
114
|
? await buildDirectPurchaseForm(commonFormValues, params)
|
|
114
115
|
: await buildPurchaseForm({
|
|
115
116
|
...commonFormValues,
|
|
116
|
-
selectedCard
|
|
117
|
+
selectedCard,
|
|
118
|
+
cardCvc: params?.card_cvv
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
window.MFS?.[
|
|
@@ -151,6 +153,10 @@ const completeMasterpassPayment = async (
|
|
|
151
153
|
return;
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
if (['5013', '5182'].includes(response.responseCode)) {
|
|
157
|
+
dispatch(setCvcRequired(true));
|
|
158
|
+
}
|
|
159
|
+
|
|
154
160
|
if (
|
|
155
161
|
response.token &&
|
|
156
162
|
(response.responseCode == '0000' || response.responseCode == '')
|
|
@@ -373,6 +379,22 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
373
379
|
dispatch(setShippingStepBusy(false));
|
|
374
380
|
}
|
|
375
381
|
}),
|
|
382
|
+
setDataSourceShippingOptions: build.mutation<CheckoutResponse, number[]>({
|
|
383
|
+
query: (pks) => ({
|
|
384
|
+
url: buildClientRequestUrl(checkout.setDataSourceShippingOption, {
|
|
385
|
+
useFormData: true
|
|
386
|
+
}),
|
|
387
|
+
method: 'POST',
|
|
388
|
+
body: {
|
|
389
|
+
data_source_shipping_options: JSON.stringify(pks)
|
|
390
|
+
}
|
|
391
|
+
}),
|
|
392
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
393
|
+
dispatch(setShippingStepBusy(true));
|
|
394
|
+
await queryFulfilled;
|
|
395
|
+
dispatch(setShippingStepBusy(false));
|
|
396
|
+
}
|
|
397
|
+
}),
|
|
376
398
|
setRetailStore: build.mutation<CheckoutResponse, SetRetailStoreParams>({
|
|
377
399
|
query: ({ retailStorePk, billingAddressPk }) => ({
|
|
378
400
|
url: buildClientRequestUrl(
|
|
@@ -672,6 +694,7 @@ export const {
|
|
|
672
694
|
useSetDeliveryOptionMutation,
|
|
673
695
|
useSetAddressesMutation,
|
|
674
696
|
useSetShippingOptionMutation,
|
|
697
|
+
useSetDataSourceShippingOptionsMutation,
|
|
675
698
|
useSetPaymentOptionMutation,
|
|
676
699
|
useSetBinNumberMutation,
|
|
677
700
|
useSetInstallmentOptionMutation,
|
package/data/server/category.ts
CHANGED
|
@@ -8,7 +8,7 @@ import logger from '../../utils/log';
|
|
|
8
8
|
|
|
9
9
|
function getCategoryDataHandler(
|
|
10
10
|
pk: number,
|
|
11
|
-
searchParams?:
|
|
11
|
+
searchParams?: { [key: string]: string | string[] | undefined },
|
|
12
12
|
headers?: Record<string, string>
|
|
13
13
|
) {
|
|
14
14
|
return async function () {
|
|
@@ -78,7 +78,7 @@ export const getCategoryData = ({
|
|
|
78
78
|
headers
|
|
79
79
|
}: {
|
|
80
80
|
pk: number;
|
|
81
|
-
searchParams?:
|
|
81
|
+
searchParams?: { [key: string]: string | string[] | undefined };
|
|
82
82
|
headers?: Record<string, string>;
|
|
83
83
|
}) => {
|
|
84
84
|
return Cache.wrap(
|
package/data/server/list.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { parse } from 'lossless-json';
|
|
|
7
7
|
import logger from '../../utils/log';
|
|
8
8
|
|
|
9
9
|
const getListDataHandler = (
|
|
10
|
-
searchParams:
|
|
10
|
+
searchParams: { [key: string]: string | string[] | undefined },
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
@@ -54,7 +54,7 @@ export const getListData = async ({
|
|
|
54
54
|
searchParams,
|
|
55
55
|
headers
|
|
56
56
|
}: {
|
|
57
|
-
searchParams:
|
|
57
|
+
searchParams: { [key: string]: string | string[] | undefined };
|
|
58
58
|
headers?: Record<string, string>;
|
|
59
59
|
}) => {
|
|
60
60
|
return Cache.wrap(
|