@akinon/next 1.42.0 → 1.43.0-rc.1
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 +39 -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/address.ts +32 -8
- 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/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(
|
package/data/server/product.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
2
2
|
import { product } from '../urls';
|
|
3
|
-
import {
|
|
4
|
-
BreadcrumbResultType,
|
|
5
|
-
ProductCategoryResult,
|
|
6
|
-
ProductResult
|
|
7
|
-
} from '../../types';
|
|
3
|
+
import { ProductCategoryResult, ProductResult } from '../../types';
|
|
8
4
|
import appFetch from '../../utils/app-fetch';
|
|
5
|
+
import logger from '../../utils/log';
|
|
9
6
|
|
|
10
7
|
type GetProduct = {
|
|
11
8
|
pk: number;
|
|
12
|
-
searchParams?:
|
|
9
|
+
searchParams?: { [key: string]: string | string[] | undefined };
|
|
13
10
|
groupProduct?: boolean;
|
|
14
11
|
};
|
|
15
12
|
|
|
@@ -50,9 +47,17 @@ const getProductDataHandler = ({
|
|
|
50
47
|
}
|
|
51
48
|
);
|
|
52
49
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
)
|
|
50
|
+
const menuItemModel = productCategoryData?.results[0]?.menuitemmodel;
|
|
51
|
+
|
|
52
|
+
if (!menuItemModel) {
|
|
53
|
+
logger.warn('menuItemModel is undefined, skipping breadcrumbData fetch', {
|
|
54
|
+
handler: 'getProductDataHandler',
|
|
55
|
+
pk
|
|
56
|
+
});
|
|
57
|
+
return { data, breadcrumbData: undefined };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const breadcrumbUrl = product.breadcrumbUrl(menuItemModel);
|
|
56
61
|
|
|
57
62
|
const breadcrumbData = await appFetch<any>(breadcrumbUrl, {
|
|
58
63
|
headers: {
|
|
@@ -74,10 +79,7 @@ export const getProductData = async ({
|
|
|
74
79
|
groupProduct
|
|
75
80
|
}: GetProduct) => {
|
|
76
81
|
return Cache.wrap(
|
|
77
|
-
CacheKey[groupProduct ? 'GroupProduct' : 'Product'](
|
|
78
|
-
pk,
|
|
79
|
-
searchParams ?? new URLSearchParams()
|
|
80
|
-
),
|
|
82
|
+
CacheKey[groupProduct ? 'GroupProduct' : 'Product'](pk, searchParams ?? {}),
|
|
81
83
|
getProductDataHandler({ pk, searchParams, groupProduct }),
|
|
82
84
|
{
|
|
83
85
|
expire: 300
|
|
@@ -7,7 +7,7 @@ import header from '../../redux/reducers/header';
|
|
|
7
7
|
|
|
8
8
|
const getSpecialPageDataHandler = (
|
|
9
9
|
pk: number,
|
|
10
|
-
searchParams:
|
|
10
|
+
searchParams: { [key: string]: string | string[] | undefined },
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
@@ -34,7 +34,7 @@ export const getSpecialPageData = async ({
|
|
|
34
34
|
headers
|
|
35
35
|
}: {
|
|
36
36
|
pk: number;
|
|
37
|
-
searchParams:
|
|
37
|
+
searchParams: { [key: string]: string | string[] | undefined };
|
|
38
38
|
headers?: Record<string, string>;
|
|
39
39
|
}) => {
|
|
40
40
|
return Cache.wrap(
|
package/data/urls.ts
CHANGED
|
@@ -83,6 +83,8 @@ export const checkout = {
|
|
|
83
83
|
setDeliveryOption: '/orders/checkout/?page=DeliveryOptionSelectionPage',
|
|
84
84
|
setAddresses: '/orders/checkout/?page=AddressSelectionPage',
|
|
85
85
|
setShippingOption: '/orders/checkout/?page=ShippingOptionSelectionPage',
|
|
86
|
+
setDataSourceShippingOption:
|
|
87
|
+
'/orders/checkout/?page=DataSourceShippingOptionSelectionPage',
|
|
86
88
|
setPaymentOption: '/orders/checkout/?page=PaymentOptionSelectionPage',
|
|
87
89
|
setBinNumber: '/orders/checkout/?page=BinNumberPage',
|
|
88
90
|
setMasterpassBinNumber: '/orders/checkout/?page=MasterpassBinNumberPage',
|
|
@@ -2,7 +2,7 @@ import settings from 'settings';
|
|
|
2
2
|
import { LayoutProps, PageProps, RootLayoutProps } from '../../types';
|
|
3
3
|
import { redirect } from 'next/navigation';
|
|
4
4
|
import { ServerVariables } from '../../utils/server-variables';
|
|
5
|
-
import {
|
|
5
|
+
import { getCachedTranslations } from '../../utils/server-translation';
|
|
6
6
|
import { ROUTES } from 'routes';
|
|
7
7
|
import logger from '../../utils/log';
|
|
8
8
|
|
|
@@ -50,7 +50,7 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
50
50
|
return redirect(ROUTES.HOME);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const translations = await
|
|
53
|
+
const translations = await getCachedTranslations(params.locale);
|
|
54
54
|
componentProps.translations = translations;
|
|
55
55
|
|
|
56
56
|
const locale = settings.localization.locales.find(
|
package/hooks/index.ts
CHANGED
|
@@ -8,4 +8,5 @@ export * from './use-media-query';
|
|
|
8
8
|
export * from './use-on-click-outside';
|
|
9
9
|
export * from './use-mobile-iframe-handler';
|
|
10
10
|
export * from './use-payment-options';
|
|
11
|
-
export * from './use-pagination';
|
|
11
|
+
export * from './use-pagination';
|
|
12
|
+
export * from './use-message-listener';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useMessageListener = () => {
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const handleMessage = (event: MessageEvent) => {
|
|
6
|
+
if (event.origin !== window.location.origin) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (event.data && typeof event.data === 'string') {
|
|
11
|
+
const messageData = JSON.parse(event.data);
|
|
12
|
+
if (messageData?.url) {
|
|
13
|
+
window.location.href = messageData.url;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
window.addEventListener('message', handleMessage);
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
window.removeEventListener('message', handleMessage);
|
|
22
|
+
};
|
|
23
|
+
}, []);
|
|
24
|
+
};
|
|
@@ -18,7 +18,8 @@ export const usePaymentOptions = () => {
|
|
|
18
18
|
pay_on_delivery: 'pz-pay-on-delivery',
|
|
19
19
|
bkm_express: 'pz-bkm',
|
|
20
20
|
credit_payment: 'pz-credit-payment',
|
|
21
|
-
masterpass: 'pz-masterpass'
|
|
21
|
+
masterpass: 'pz-masterpass',
|
|
22
|
+
gpay: 'pz-gpay'
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
const isInitialTypeIncluded = (type: string) => initialTypes.has(type);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CacheHandler } from '@neshca/cache-handler';
|
|
2
|
+
import createLruHandler from '@neshca/cache-handler/local-lru';
|
|
3
|
+
import createRedisHandler from '@neshca/cache-handler/redis-stack';
|
|
4
|
+
import { createClient } from 'redis';
|
|
5
|
+
|
|
6
|
+
CacheHandler.onCreation(async () => {
|
|
7
|
+
const redisUrl = `redis://${process.env.CACHE_HOST}:${
|
|
8
|
+
process.env.CACHE_PORT
|
|
9
|
+
}/${process.env.CACHE_BUCKET ?? '0'}`;
|
|
10
|
+
|
|
11
|
+
const client = createClient({
|
|
12
|
+
url: redisUrl
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
client.on('error', (error) => {
|
|
16
|
+
console.error('Redis client error', { redisUrl, error });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
await client.connect();
|
|
20
|
+
|
|
21
|
+
const redisHandler = await createRedisHandler({
|
|
22
|
+
client,
|
|
23
|
+
timeoutMs: 5000
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const localHandler = createLruHandler();
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
handlers: [redisHandler, localHandler]
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export default CacheHandler;
|
package/lib/cache.ts
CHANGED
|
@@ -20,13 +20,16 @@ const hashCacheKey = (object?: Record<string, string>) => {
|
|
|
20
20
|
return `_${encodeURIComponent(cacheKey)}`;
|
|
21
21
|
};
|
|
22
22
|
export const CacheKey = {
|
|
23
|
-
List: (
|
|
23
|
+
List: (
|
|
24
|
+
searchParams: { [key: string]: string | string[] | undefined },
|
|
25
|
+
headers?: Record<string, string>
|
|
26
|
+
) =>
|
|
24
27
|
`list_${encodeURIComponent(JSON.stringify(searchParams))}${hashCacheKey(
|
|
25
28
|
headers
|
|
26
29
|
)}`,
|
|
27
30
|
Category: (
|
|
28
31
|
pk: number,
|
|
29
|
-
searchParams?:
|
|
32
|
+
searchParams?: { [key: string]: string | string[] | undefined },
|
|
30
33
|
headers?: Record<string, string>
|
|
31
34
|
) =>
|
|
32
35
|
`category_${pk}_${encodeURIComponent(
|
|
@@ -35,15 +38,20 @@ export const CacheKey = {
|
|
|
35
38
|
CategorySlug: (slug: string) => `category_${slug}`,
|
|
36
39
|
SpecialPage: (
|
|
37
40
|
pk: number,
|
|
38
|
-
searchParams:
|
|
41
|
+
searchParams: { [key: string]: string | string[] | undefined },
|
|
39
42
|
headers?: Record<string, string>
|
|
40
43
|
) =>
|
|
41
44
|
`special_page_${pk}_${encodeURIComponent(
|
|
42
45
|
JSON.stringify(searchParams)
|
|
43
46
|
)}${hashCacheKey(headers)}`,
|
|
44
|
-
Product: (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
Product: (
|
|
48
|
+
pk: number,
|
|
49
|
+
searchParams: { [key: string]: string | string[] | undefined }
|
|
50
|
+
) => `product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
|
|
51
|
+
GroupProduct: (
|
|
52
|
+
pk: number,
|
|
53
|
+
searchParams: { [key: string]: string | string[] | undefined }
|
|
54
|
+
) =>
|
|
47
55
|
`group_product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
|
|
48
56
|
FlatPage: (pk: number) => `flat_page_${pk}`,
|
|
49
57
|
LandingPage: (pk: number) => `landing_page_${pk}`,
|
|
@@ -158,6 +166,10 @@ export class Cache {
|
|
|
158
166
|
handler: () => Promise<T>,
|
|
159
167
|
options?: CacheOptions
|
|
160
168
|
): Promise<T> {
|
|
169
|
+
if (Settings.usePrettyUrlRoute) {
|
|
170
|
+
return await handler();
|
|
171
|
+
}
|
|
172
|
+
|
|
161
173
|
const requiredVariables = [
|
|
162
174
|
process.env.CACHE_HOST,
|
|
163
175
|
process.env.CACHE_PORT,
|
package/middlewares/default.ts
CHANGED
|
@@ -84,14 +84,40 @@ const withPzDefault =
|
|
|
84
84
|
req.nextUrl.pathname.includes('/orders/hooks/') ||
|
|
85
85
|
req.nextUrl.pathname.includes('/orders/checkout-with-token/')
|
|
86
86
|
) {
|
|
87
|
-
|
|
87
|
+
const segment = url.searchParams.get('segment');
|
|
88
|
+
const currency = url.searchParams.get('currency');
|
|
89
|
+
|
|
90
|
+
const headers = {};
|
|
91
|
+
|
|
92
|
+
if (segment) {
|
|
93
|
+
headers['X-Segment-Id'] = segment;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (currency) {
|
|
97
|
+
headers['x-currency'] = currency;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const response = NextResponse.rewrite(
|
|
88
101
|
new URL(
|
|
89
102
|
`${Settings.commerceUrl}${req.nextUrl.pathname.replace(
|
|
90
103
|
urlLocaleMatcherRegex,
|
|
91
104
|
''
|
|
92
105
|
)}`
|
|
93
|
-
)
|
|
106
|
+
),
|
|
107
|
+
{
|
|
108
|
+
headers
|
|
109
|
+
}
|
|
94
110
|
);
|
|
111
|
+
|
|
112
|
+
if (segment) {
|
|
113
|
+
response.cookies.set('pz-segment', segment);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (currency) {
|
|
117
|
+
response.cookies.set('pz-external-currency', currency);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return response;
|
|
95
121
|
}
|
|
96
122
|
|
|
97
123
|
if (req.nextUrl.pathname.startsWith('/orders/redirection/')) {
|
|
@@ -203,6 +229,15 @@ const withPzDefault =
|
|
|
203
229
|
);
|
|
204
230
|
}
|
|
205
231
|
|
|
232
|
+
if (
|
|
233
|
+
Settings.usePrettyUrlRoute &&
|
|
234
|
+
url.searchParams.toString().length > 0
|
|
235
|
+
) {
|
|
236
|
+
url.pathname =
|
|
237
|
+
url.pathname +
|
|
238
|
+
`searchparams|${url.searchParams.toString()}`;
|
|
239
|
+
}
|
|
240
|
+
|
|
206
241
|
Settings.rewrites.forEach((rewrite) => {
|
|
207
242
|
url.pathname = url.pathname.replace(
|
|
208
243
|
rewrite.source,
|
|
@@ -56,6 +56,10 @@ const resolvePrettyUrl = async (pathname: string, ip: string | null) => {
|
|
|
56
56
|
const withPrettyUrl =
|
|
57
57
|
(middleware: NextMiddleware) =>
|
|
58
58
|
async (req: PzNextRequest, event: NextFetchEvent) => {
|
|
59
|
+
if (Settings.usePrettyUrlRoute) {
|
|
60
|
+
return middleware(req, event);
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
const url = req.nextUrl.clone();
|
|
60
64
|
const matchedLanguagePrefix = url.pathname.match(
|
|
61
65
|
urlLocaleMatcherRegex
|
|
@@ -11,6 +11,10 @@ import { ROUTES } from 'routes';
|
|
|
11
11
|
const withUrlRedirection =
|
|
12
12
|
(middleware: NextMiddleware) =>
|
|
13
13
|
async (req: PzNextRequest, event: NextFetchEvent) => {
|
|
14
|
+
if (settings.usePrettyUrlRoute) {
|
|
15
|
+
return middleware(req, event);
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
const url = req.nextUrl.clone();
|
|
15
19
|
const ip = req.headers.get('x-forwarded-for') ?? '';
|
|
16
20
|
const pathnameWithoutLocale = url.pathname.replace(
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.43.0-rc.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -20,21 +20,22 @@
|
|
|
20
20
|
"@opentelemetry/sdk-trace-node": "1.19.0",
|
|
21
21
|
"@opentelemetry/semantic-conventions": "1.19.0",
|
|
22
22
|
"@reduxjs/toolkit": "1.9.7",
|
|
23
|
+
"@neshca/cache-handler": "1.5.1",
|
|
23
24
|
"cross-spawn": "7.0.3",
|
|
24
25
|
"generic-pool": "3.9.0",
|
|
25
26
|
"react-redux": "8.1.3",
|
|
26
27
|
"react-string-replace": "1.1.1",
|
|
27
|
-
"redis": "4.
|
|
28
|
-
"semver": "7.
|
|
28
|
+
"redis": "4.6.13",
|
|
29
|
+
"semver": "7.6.2",
|
|
29
30
|
"set-cookie-parser": "2.6.0"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
33
|
+
"@akinon/eslint-plugin-projectzero": "1.43.0-rc.1",
|
|
32
34
|
"@types/react-redux": "7.1.30",
|
|
33
35
|
"@types/set-cookie-parser": "2.4.7",
|
|
34
36
|
"@typescript-eslint/eslint-plugin": "6.7.4",
|
|
35
37
|
"@typescript-eslint/parser": "6.7.4",
|
|
36
38
|
"eslint": "^8.14.0",
|
|
37
|
-
"@akinon/eslint-plugin-projectzero": "1.42.0",
|
|
38
39
|
"eslint-config-prettier": "8.5.0"
|
|
39
40
|
}
|
|
40
41
|
}
|
package/plugins.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ declare module '@akinon/pz-masterpass/src/utils' {
|
|
|
12
12
|
declare module '@akinon/pz-masterpass/src/redux/reducer' {
|
|
13
13
|
export const setError: any;
|
|
14
14
|
export const setOtpModalVisible: any;
|
|
15
|
+
export const setCvcRequired: any;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
declare module '@akinon/pz-otp' {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
setPreOrder,
|
|
17
17
|
setRetailStores,
|
|
18
18
|
setShippingOptions,
|
|
19
|
+
setDataSourceShippingOptions,
|
|
19
20
|
setShippingStepCompleted,
|
|
20
21
|
setCreditPaymentOptions
|
|
21
22
|
} from '../../redux/reducers/checkout';
|
|
@@ -26,10 +27,11 @@ import { getCookie, setCookie } from '../../utils';
|
|
|
26
27
|
import settings from 'settings';
|
|
27
28
|
import { LocaleUrlStrategy } from '../../localization';
|
|
28
29
|
import { showMobile3dIframe } from '../../utils/mobile-3d-iframe';
|
|
30
|
+
import { showRedirectionIframe } from '../../utils/redirection-iframe';
|
|
29
31
|
|
|
30
32
|
interface CheckoutResult {
|
|
31
33
|
payload: {
|
|
32
|
-
errors?:
|
|
34
|
+
errors?: Record<string, string[]>;
|
|
33
35
|
pre_order?: PreOrder;
|
|
34
36
|
context_list?: CheckoutContext[];
|
|
35
37
|
};
|
|
@@ -73,6 +75,7 @@ export const preOrderMiddleware: Middleware = ({
|
|
|
73
75
|
deliveryOptions,
|
|
74
76
|
addressList: addresses,
|
|
75
77
|
shippingOptions,
|
|
78
|
+
dataSourceShippingOptions,
|
|
76
79
|
paymentOptions,
|
|
77
80
|
installmentOptions
|
|
78
81
|
} = getState().checkout;
|
|
@@ -125,6 +128,22 @@ export const preOrderMiddleware: Middleware = ({
|
|
|
125
128
|
dispatch(apiEndpoints.setShippingOption.initiate(shippingOptions[0].pk));
|
|
126
129
|
}
|
|
127
130
|
|
|
131
|
+
if (
|
|
132
|
+
dataSourceShippingOptions.length > 0 &&
|
|
133
|
+
!preOrder.data_source_shipping_options
|
|
134
|
+
) {
|
|
135
|
+
const selectedDataSourceShippingOptionsPks =
|
|
136
|
+
dataSourceShippingOptions.map(
|
|
137
|
+
(opt) => opt.data_source_shipping_options[0].pk
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
dispatch(
|
|
141
|
+
apiEndpoints.setDataSourceShippingOptions.initiate(
|
|
142
|
+
selectedDataSourceShippingOptionsPks
|
|
143
|
+
)
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
128
147
|
if (!preOrder.payment_option && paymentOptions.length > 0) {
|
|
129
148
|
dispatch(apiEndpoints.setPaymentOption.initiate(paymentOptions[0].pk));
|
|
130
149
|
}
|
|
@@ -163,6 +182,7 @@ export const contextListMiddleware: Middleware = ({
|
|
|
163
182
|
if (result?.payload?.context_list) {
|
|
164
183
|
result.payload.context_list.forEach((context) => {
|
|
165
184
|
const redirectUrl = context.page_context.redirect_url;
|
|
185
|
+
const isIframe = context.page_context.is_frame ?? false;
|
|
166
186
|
|
|
167
187
|
if (redirectUrl) {
|
|
168
188
|
const currentLocale = getCookie('pz-locale');
|
|
@@ -181,16 +201,19 @@ export const contextListMiddleware: Middleware = ({
|
|
|
181
201
|
}
|
|
182
202
|
|
|
183
203
|
const urlObj = new URL(url, window.location.origin);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
/iPad|iPhone|iPod|Android/i.test(navigator.userAgent)) &&
|
|
204
|
+
const isMobileDevice =
|
|
205
|
+
isMobileApp ||
|
|
206
|
+
/iPad|iPhone|iPod|Android/i.test(navigator.userAgent);
|
|
207
|
+
const isIframePaymentOptionExcluded =
|
|
189
208
|
!settings.checkout?.iframeExcludedPaymentOptions?.includes(
|
|
190
209
|
result.payload?.pre_order?.payment_option?.slug
|
|
191
|
-
)
|
|
192
|
-
)
|
|
210
|
+
);
|
|
211
|
+
urlObj.searchParams.set('t', new Date().getTime().toString());
|
|
212
|
+
|
|
213
|
+
if (isMobileDevice && !isIframePaymentOptionExcluded) {
|
|
193
214
|
showMobile3dIframe(urlObj.toString());
|
|
215
|
+
} else if (isIframe && !isIframePaymentOptionExcluded) {
|
|
216
|
+
showRedirectionIframe(urlObj.toString());
|
|
194
217
|
} else {
|
|
195
218
|
window.location.href = urlObj.toString();
|
|
196
219
|
}
|
|
@@ -220,12 +243,20 @@ export const contextListMiddleware: Middleware = ({
|
|
|
220
243
|
dispatch(setShippingOptions(context.page_context.shipping_options));
|
|
221
244
|
}
|
|
222
245
|
|
|
246
|
+
if (context.page_context.data_sources) {
|
|
247
|
+
dispatch(
|
|
248
|
+
setDataSourceShippingOptions(context.page_context.data_sources)
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
223
252
|
if (context.page_context.payment_options) {
|
|
224
253
|
dispatch(setPaymentOptions(context.page_context.payment_options));
|
|
225
254
|
}
|
|
226
255
|
|
|
227
256
|
if (context.page_context.credit_payment_options) {
|
|
228
|
-
dispatch(
|
|
257
|
+
dispatch(
|
|
258
|
+
setCreditPaymentOptions(context.page_context.credit_payment_options)
|
|
259
|
+
);
|
|
229
260
|
}
|
|
230
261
|
|
|
231
262
|
if (context.page_context.payment_choices) {
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
CheckoutCreditPaymentOption,
|
|
15
15
|
PreOrder,
|
|
16
16
|
RetailStore,
|
|
17
|
-
ShippingOption
|
|
17
|
+
ShippingOption,
|
|
18
|
+
DataSource
|
|
18
19
|
} from '../../types';
|
|
19
20
|
|
|
20
21
|
export interface CheckoutState {
|
|
21
|
-
|
|
22
|
-
errors: any;
|
|
22
|
+
errors: Record<string, string[]>;
|
|
23
23
|
hasGiftBox: boolean;
|
|
24
24
|
canGuestPurchase: boolean;
|
|
25
25
|
steps: {
|
|
@@ -37,6 +37,7 @@ export interface CheckoutState {
|
|
|
37
37
|
addressList: Address[];
|
|
38
38
|
deliveryOptions: DeliveryOption[];
|
|
39
39
|
shippingOptions: ShippingOption[];
|
|
40
|
+
dataSourceShippingOptions: DataSource[];
|
|
40
41
|
paymentOptions: PaymentOption[];
|
|
41
42
|
creditPaymentOptions: CheckoutCreditPaymentOption[];
|
|
42
43
|
selectedCreditPaymentPk: number;
|
|
@@ -68,6 +69,7 @@ const initialState: CheckoutState = {
|
|
|
68
69
|
addressList: [],
|
|
69
70
|
deliveryOptions: [],
|
|
70
71
|
shippingOptions: [],
|
|
72
|
+
dataSourceShippingOptions: [],
|
|
71
73
|
paymentOptions: [],
|
|
72
74
|
creditPaymentOptions: [],
|
|
73
75
|
selectedCreditPaymentPk: null,
|
|
@@ -122,6 +124,9 @@ const checkoutSlice = createSlice({
|
|
|
122
124
|
setShippingOptions(state, { payload }) {
|
|
123
125
|
state.shippingOptions = payload;
|
|
124
126
|
},
|
|
127
|
+
setDataSourceShippingOptions(state, { payload }) {
|
|
128
|
+
state.dataSourceShippingOptions = payload;
|
|
129
|
+
},
|
|
125
130
|
setPaymentOptions(state, { payload }) {
|
|
126
131
|
state.paymentOptions = payload;
|
|
127
132
|
},
|
|
@@ -169,6 +174,7 @@ export const {
|
|
|
169
174
|
setAddressList,
|
|
170
175
|
setDeliveryOptions,
|
|
171
176
|
setShippingOptions,
|
|
177
|
+
setDataSourceShippingOptions,
|
|
172
178
|
setPaymentOptions,
|
|
173
179
|
setCreditPaymentOptions,
|
|
174
180
|
setSelectedCreditPaymentPk,
|
package/redux/reducers/config.ts
CHANGED