@akinon/next 1.98.0 → 1.99.0-rc.66
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 +1319 -41
- package/__tests__/next-config.test.ts +1 -10
- package/__tests__/redirect.test.ts +319 -0
- package/api/image-proxy.ts +75 -0
- package/api/similar-product-list.ts +84 -0
- package/api/similar-products.ts +120 -0
- package/components/accordion.tsx +20 -5
- package/components/file-input.tsx +65 -3
- package/components/input.tsx +2 -0
- package/components/link.tsx +16 -12
- package/components/modal.tsx +32 -16
- package/components/plugin-module.tsx +32 -4
- package/data/client/checkout.ts +4 -2
- package/data/server/basket.ts +72 -0
- package/data/server/category.ts +44 -24
- package/data/server/flatpage.ts +16 -12
- package/data/server/landingpage.ts +16 -12
- package/data/server/list.ts +23 -13
- package/data/server/product.ts +66 -39
- package/data/server/special-page.ts +16 -12
- package/data/urls.ts +5 -1
- package/hocs/server/with-segment-defaults.tsx +5 -2
- package/hooks/use-localization.ts +2 -3
- package/jest.config.js +7 -1
- package/lib/cache.ts +2 -0
- package/middlewares/complete-gpay.ts +2 -1
- package/middlewares/complete-masterpass.ts +2 -1
- package/middlewares/default.ts +50 -13
- package/middlewares/locale.ts +9 -1
- package/middlewares/redirection-payment.ts +2 -1
- package/middlewares/saved-card-redirection.ts +2 -1
- package/middlewares/three-d-redirection.ts +2 -1
- package/middlewares/url-redirection.ts +8 -14
- package/package.json +3 -3
- package/plugins.d.ts +8 -5
- package/plugins.js +3 -1
- package/redux/middlewares/checkout.ts +5 -1
- package/types/commerce/order.ts +1 -0
- package/types/index.ts +34 -1
- package/utils/app-fetch.ts +7 -2
- package/utils/redirect-ignore.ts +35 -0
- package/utils/redirect.ts +31 -6
- package/with-pz-config.js +1 -5
|
@@ -1,8 +1,70 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
1
2
|
import { forwardRef } from 'react';
|
|
2
|
-
import {
|
|
3
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { FileInputProps } from '../types';
|
|
3
6
|
|
|
4
7
|
export const FileInput = forwardRef<HTMLInputElement, FileInputProps>(
|
|
5
|
-
function
|
|
6
|
-
|
|
8
|
+
function FileInput(
|
|
9
|
+
{
|
|
10
|
+
buttonClassName,
|
|
11
|
+
onChange,
|
|
12
|
+
fileClassName,
|
|
13
|
+
fileNameWrapperClassName,
|
|
14
|
+
fileInputClassName,
|
|
15
|
+
...props
|
|
16
|
+
},
|
|
17
|
+
ref
|
|
18
|
+
) {
|
|
19
|
+
const { t } = useLocalization();
|
|
20
|
+
const [fileNames, setFileNames] = useState<string[]>([]);
|
|
21
|
+
|
|
22
|
+
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
23
|
+
const files = Array.from(event.target.files || []);
|
|
24
|
+
setFileNames(files.map((file) => file.name));
|
|
25
|
+
|
|
26
|
+
if (onChange) {
|
|
27
|
+
onChange(event);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="relative">
|
|
33
|
+
<input
|
|
34
|
+
type="file"
|
|
35
|
+
{...props}
|
|
36
|
+
ref={ref}
|
|
37
|
+
className={twMerge(
|
|
38
|
+
'absolute inset-0 w-full h-full opacity-0 cursor-pointer',
|
|
39
|
+
fileInputClassName
|
|
40
|
+
)}
|
|
41
|
+
onChange={handleFileChange}
|
|
42
|
+
/>
|
|
43
|
+
<button
|
|
44
|
+
type="button"
|
|
45
|
+
className={twMerge(
|
|
46
|
+
'bg-primary text-white py-2 px-4 text-sm',
|
|
47
|
+
buttonClassName
|
|
48
|
+
)}
|
|
49
|
+
>
|
|
50
|
+
{t('common.file_input.select_file')}
|
|
51
|
+
</button>
|
|
52
|
+
<div
|
|
53
|
+
className={twMerge('mt-1 text-gray-500', fileNameWrapperClassName)}
|
|
54
|
+
>
|
|
55
|
+
{fileNames.length > 0 ? (
|
|
56
|
+
<ul className={twMerge('list-disc pl-4 text-xs', fileClassName)}>
|
|
57
|
+
{fileNames.map((name, index) => (
|
|
58
|
+
<li key={index}>{name}</li>
|
|
59
|
+
))}
|
|
60
|
+
</ul>
|
|
61
|
+
) : (
|
|
62
|
+
<span className={twMerge('text-xs', fileClassName)}>
|
|
63
|
+
{t('common.file_input.no_file')}
|
|
64
|
+
</span>
|
|
65
|
+
)}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
7
69
|
}
|
|
8
70
|
);
|
package/components/input.tsx
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { forwardRef, FocusEvent, useState, Ref } from 'react';
|
|
3
3
|
import { Controller } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
4
6
|
import { PatternFormat, PatternFormatProps } from 'react-number-format';
|
|
5
7
|
import { InputProps } from '../types';
|
|
6
8
|
import { twMerge } from 'tailwind-merge';
|
package/components/link.tsx
CHANGED
|
@@ -10,7 +10,9 @@ 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();
|
|
@@ -26,19 +28,21 @@ export const Link = ({ children, href, ...rest }: LinkProps) => {
|
|
|
26
28
|
return href;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
if (typeof href === 'string' && !href.startsWith('http')) {
|
|
32
|
+
const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
|
|
33
|
+
const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
|
|
34
|
+
|
|
35
|
+
if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
|
|
36
|
+
return hrefWithLocale;
|
|
37
|
+
} else if (
|
|
38
|
+
localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
|
|
39
|
+
locale !== defaultLocaleValue
|
|
40
|
+
) {
|
|
41
|
+
return hrefWithLocale;
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
return href
|
|
45
|
+
return href;
|
|
42
46
|
}, [href, defaultLocaleValue, locale, localeUrlStrategy]);
|
|
43
47
|
|
|
44
48
|
return (
|
package/components/modal.tsx
CHANGED
|
@@ -4,16 +4,7 @@ import { ReactPortal } from './react-portal';
|
|
|
4
4
|
import { Icon } from './icon';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { useEffect } from 'react';
|
|
7
|
-
|
|
8
|
-
export interface ModalProps {
|
|
9
|
-
portalId: string;
|
|
10
|
-
children?: React.ReactNode;
|
|
11
|
-
open?: boolean;
|
|
12
|
-
setOpen?: (open: boolean) => void;
|
|
13
|
-
title?: React.ReactNode;
|
|
14
|
-
showCloseButton?: React.ReactNode;
|
|
15
|
-
className?: string;
|
|
16
|
-
}
|
|
7
|
+
import { ModalProps } from '../types';
|
|
17
8
|
|
|
18
9
|
export const Modal = (props: ModalProps) => {
|
|
19
10
|
const {
|
|
@@ -23,7 +14,14 @@ export const Modal = (props: ModalProps) => {
|
|
|
23
14
|
setOpen,
|
|
24
15
|
title = '',
|
|
25
16
|
showCloseButton = true,
|
|
26
|
-
className
|
|
17
|
+
className,
|
|
18
|
+
overlayClassName,
|
|
19
|
+
headerWrapperClassName,
|
|
20
|
+
titleClassName,
|
|
21
|
+
closeButtonClassName,
|
|
22
|
+
iconName = 'close',
|
|
23
|
+
iconSize = 16,
|
|
24
|
+
iconClassName
|
|
27
25
|
} = props;
|
|
28
26
|
|
|
29
27
|
useEffect(() => {
|
|
@@ -38,7 +36,12 @@ export const Modal = (props: ModalProps) => {
|
|
|
38
36
|
|
|
39
37
|
return (
|
|
40
38
|
<ReactPortal wrapperId={portalId}>
|
|
41
|
-
<div
|
|
39
|
+
<div
|
|
40
|
+
className={twMerge(
|
|
41
|
+
'fixed top-0 left-0 w-screen h-screen bg-primary bg-opacity-60 z-50',
|
|
42
|
+
overlayClassName
|
|
43
|
+
)}
|
|
44
|
+
/>
|
|
42
45
|
<section
|
|
43
46
|
className={twMerge(
|
|
44
47
|
'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
|
|
@@ -46,15 +49,28 @@ export const Modal = (props: ModalProps) => {
|
|
|
46
49
|
)}
|
|
47
50
|
>
|
|
48
51
|
{(showCloseButton || title) && (
|
|
49
|
-
<div
|
|
50
|
-
|
|
52
|
+
<div
|
|
53
|
+
className={twMerge(
|
|
54
|
+
'flex px-6 py-4 border-b border-gray-400',
|
|
55
|
+
headerWrapperClassName
|
|
56
|
+
)}
|
|
57
|
+
>
|
|
58
|
+
{title && (
|
|
59
|
+
<h3 className={twMerge('text-lg font-light', titleClassName)}>
|
|
60
|
+
{title}
|
|
61
|
+
</h3>
|
|
62
|
+
)}
|
|
51
63
|
{showCloseButton && (
|
|
52
64
|
<button
|
|
53
65
|
type="button"
|
|
54
66
|
onClick={() => setOpen(false)}
|
|
55
|
-
className=
|
|
67
|
+
className={twMerge('ml-auto', closeButtonClassName)}
|
|
56
68
|
>
|
|
57
|
-
<Icon
|
|
69
|
+
<Icon
|
|
70
|
+
name={iconName}
|
|
71
|
+
size={iconSize}
|
|
72
|
+
className={iconClassName}
|
|
73
|
+
/>
|
|
58
74
|
</button>
|
|
59
75
|
)}
|
|
60
76
|
</div>
|
|
@@ -21,7 +21,9 @@ enum Plugin {
|
|
|
21
21
|
Akifast = 'pz-akifast',
|
|
22
22
|
MultiBasket = 'pz-multi-basket',
|
|
23
23
|
SavedCard = 'pz-saved-card',
|
|
24
|
-
|
|
24
|
+
Hepsipay = 'pz-hepsipay',
|
|
25
|
+
FlowPayment = 'pz-flow-payment',
|
|
26
|
+
SimilarProducts = 'pz-similar-products'
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export enum Component {
|
|
@@ -47,7 +49,16 @@ export enum Component {
|
|
|
47
49
|
AkifastCheckoutButton = 'CheckoutButton',
|
|
48
50
|
MultiBasket = 'MultiBasket',
|
|
49
51
|
SavedCard = 'SavedCardOption',
|
|
50
|
-
|
|
52
|
+
Hepsipay = 'Hepsipay',
|
|
53
|
+
FlowPayment = 'FlowPayment',
|
|
54
|
+
SimilarProductsModal = 'SimilarProductsModal',
|
|
55
|
+
SimilarProductsFilterSidebar = 'SimilarProductsFilterSidebar',
|
|
56
|
+
SimilarProductsResultsGrid = 'SimilarProductsResultsGrid',
|
|
57
|
+
SimilarProductsPlugin = 'SimilarProductsPlugin',
|
|
58
|
+
ProductImageSearchFeature = 'ProductImageSearchFeature',
|
|
59
|
+
ImageSearchButton = 'ImageSearchButton',
|
|
60
|
+
HeaderImageSearchFeature = 'HeaderImageSearchFeature',
|
|
61
|
+
IyzicoSavedCard = 'IyzicoSavedCardOption'
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
const PluginComponents = new Map([
|
|
@@ -80,8 +91,21 @@ const PluginComponents = new Map([
|
|
|
80
91
|
[Component.AkifastQuickLoginButton, Component.AkifastCheckoutButton]
|
|
81
92
|
],
|
|
82
93
|
[Plugin.MultiBasket, [Component.MultiBasket]],
|
|
83
|
-
[Plugin.SavedCard, [Component.SavedCard]],
|
|
84
|
-
[Plugin.
|
|
94
|
+
[Plugin.SavedCard, [Component.SavedCard, Component.IyzicoSavedCard]],
|
|
95
|
+
[Plugin.Hepsipay, [Component.Hepsipay]],
|
|
96
|
+
[Plugin.FlowPayment, [Component.FlowPayment]],
|
|
97
|
+
[
|
|
98
|
+
Plugin.SimilarProducts,
|
|
99
|
+
[
|
|
100
|
+
Component.SimilarProductsModal,
|
|
101
|
+
Component.SimilarProductsFilterSidebar,
|
|
102
|
+
Component.SimilarProductsResultsGrid,
|
|
103
|
+
Component.SimilarProductsPlugin,
|
|
104
|
+
Component.ProductImageSearchFeature,
|
|
105
|
+
Component.ImageSearchButton,
|
|
106
|
+
Component.HeaderImageSearchFeature
|
|
107
|
+
]
|
|
108
|
+
]
|
|
85
109
|
]);
|
|
86
110
|
|
|
87
111
|
const getPlugin = (component: Component) => {
|
|
@@ -146,8 +170,12 @@ export default function PluginModule({
|
|
|
146
170
|
promise = import(`${'@akinon/pz-multi-basket'}`);
|
|
147
171
|
} else if (plugin === Plugin.SavedCard) {
|
|
148
172
|
promise = import(`${'@akinon/pz-saved-card'}`);
|
|
173
|
+
} else if (plugin === Plugin.Hepsipay) {
|
|
174
|
+
promise = import(`${'@akinon/pz-hepsipay'}`);
|
|
149
175
|
} else if (plugin === Plugin.FlowPayment) {
|
|
150
176
|
promise = import(`${'@akinon/pz-flow-payment'}`);
|
|
177
|
+
} else if (plugin === Plugin.SimilarProducts) {
|
|
178
|
+
promise = import(`${'@akinon/pz-similar-products'}`);
|
|
151
179
|
}
|
|
152
180
|
} catch (error) {
|
|
153
181
|
logger.error(error);
|
package/data/client/checkout.ts
CHANGED
|
@@ -35,8 +35,10 @@ import {
|
|
|
35
35
|
|
|
36
36
|
interface CheckoutResponse {
|
|
37
37
|
pre_order?: PreOrder;
|
|
38
|
-
errors
|
|
39
|
-
non_field_errors
|
|
38
|
+
errors?: {
|
|
39
|
+
non_field_errors?: string;
|
|
40
|
+
sample_products?: string[];
|
|
41
|
+
[key: string]: string | string[] | undefined;
|
|
40
42
|
};
|
|
41
43
|
context_list?: CheckoutContext[];
|
|
42
44
|
template_name?: string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Cache, CacheKey } from '../../lib/cache';
|
|
2
|
+
import { basket } from '../../data/urls';
|
|
3
|
+
import { Basket } from '../../types';
|
|
4
|
+
import appFetch from '../../utils/app-fetch';
|
|
5
|
+
import { ServerVariables } from '../../utils/server-variables';
|
|
6
|
+
import logger from '../../utils/log';
|
|
7
|
+
|
|
8
|
+
type GetBasketParams = {
|
|
9
|
+
locale?: string;
|
|
10
|
+
currency?: string;
|
|
11
|
+
namespace?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getBasketDataHandler = ({
|
|
15
|
+
locale,
|
|
16
|
+
currency,
|
|
17
|
+
namespace
|
|
18
|
+
}: GetBasketParams) => {
|
|
19
|
+
return async function () {
|
|
20
|
+
try {
|
|
21
|
+
const url = namespace
|
|
22
|
+
? basket.getBasketDetail(namespace)
|
|
23
|
+
: basket.getBasket;
|
|
24
|
+
|
|
25
|
+
const basketData = await appFetch<{ basket: Basket }>({
|
|
26
|
+
url,
|
|
27
|
+
locale,
|
|
28
|
+
currency,
|
|
29
|
+
init: {
|
|
30
|
+
headers: {
|
|
31
|
+
Accept: 'application/json',
|
|
32
|
+
'Content-Type': 'application/json'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (!basketData?.basket) {
|
|
38
|
+
logger.warn('Basket data is undefined', {
|
|
39
|
+
handler: 'getBasketDataHandler',
|
|
40
|
+
namespace
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return basketData;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
logger.error('Error fetching basket data', {
|
|
47
|
+
handler: 'getBasketDataHandler',
|
|
48
|
+
error,
|
|
49
|
+
namespace
|
|
50
|
+
});
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const getBasketData = async ({
|
|
57
|
+
locale = ServerVariables.locale,
|
|
58
|
+
currency = ServerVariables.currency,
|
|
59
|
+
namespace
|
|
60
|
+
}: GetBasketParams = {}) => {
|
|
61
|
+
return Cache.wrap(
|
|
62
|
+
CacheKey.Basket(namespace),
|
|
63
|
+
locale,
|
|
64
|
+
getBasketDataHandler({ locale, currency, namespace }),
|
|
65
|
+
{
|
|
66
|
+
expire: 0,
|
|
67
|
+
cache: false
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
|
package/data/server/category.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { category, product } from '../urls';
|
|
|
5
5
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
6
6
|
import { parse } from 'lossless-json';
|
|
7
7
|
import logger from '../../utils/log';
|
|
8
|
-
import { headers as nHeaders } from 'next/headers';
|
|
9
8
|
import { ServerVariables } from '../../utils/server-variables';
|
|
10
9
|
|
|
11
10
|
function getCategoryDataHandler(
|
|
@@ -18,19 +17,30 @@ function getCategoryDataHandler(
|
|
|
18
17
|
return async function () {
|
|
19
18
|
const params = generateCommerceSearchParams(searchParams);
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
let rawData: string;
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
rawData = await appFetch<string>({
|
|
24
|
+
url: `${category.getCategoryByPk(pk)}${params ? params : ''}`,
|
|
25
|
+
locale,
|
|
26
|
+
currency,
|
|
27
|
+
init: {
|
|
28
|
+
headers: {
|
|
29
|
+
Accept: 'application/json',
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
...(headers ?? {})
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
responseType: FetchResponseType.TEXT
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
logger.error('Failed to fetch category data', {
|
|
38
|
+
handler: 'getCategoryDataHandler',
|
|
39
|
+
pk,
|
|
40
|
+
error: error.message
|
|
41
|
+
});
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
34
44
|
|
|
35
45
|
let data: GetCategoryResponse;
|
|
36
46
|
|
|
@@ -64,17 +74,27 @@ function getCategoryDataHandler(
|
|
|
64
74
|
return { data, breadcrumbData: undefined };
|
|
65
75
|
}
|
|
66
76
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
let breadcrumbData: { menu?: unknown } = {};
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
breadcrumbData = await appFetch<{ menu?: unknown }>({
|
|
81
|
+
url: product.breadcrumbUrl(menuItemModel),
|
|
82
|
+
locale,
|
|
83
|
+
currency,
|
|
84
|
+
init: {
|
|
85
|
+
headers: {
|
|
86
|
+
Accept: 'application/json',
|
|
87
|
+
'Content-Type': 'application/json'
|
|
88
|
+
}
|
|
75
89
|
}
|
|
76
|
-
}
|
|
77
|
-
})
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
logger.warn('Failed to fetch breadcrumb data', {
|
|
93
|
+
handler: 'getCategoryDataHandler',
|
|
94
|
+
pk,
|
|
95
|
+
error: error.message
|
|
96
|
+
});
|
|
97
|
+
}
|
|
78
98
|
|
|
79
99
|
return { data, breadcrumbData: breadcrumbData?.menu };
|
|
80
100
|
};
|
package/data/server/flatpage.ts
CHANGED
|
@@ -11,20 +11,24 @@ const getFlatPageDataHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
try {
|
|
15
|
+
const data = await appFetch<FlatPage>({
|
|
16
|
+
url: flatpage.getFlatPageByPk(pk),
|
|
17
|
+
locale,
|
|
18
|
+
currency,
|
|
19
|
+
init: {
|
|
20
|
+
headers: {
|
|
21
|
+
Accept: 'application/json',
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
...(headers ?? {})
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
+
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
return data;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
28
32
|
};
|
|
29
33
|
};
|
|
30
34
|
|
|
@@ -11,20 +11,24 @@ const getLandingPageHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
try {
|
|
15
|
+
const data = await appFetch<LandingPage>({
|
|
16
|
+
url: landingpage.getLandingPageByPk(pk),
|
|
17
|
+
locale,
|
|
18
|
+
currency,
|
|
19
|
+
init: {
|
|
20
|
+
headers: {
|
|
21
|
+
Accept: 'application/json',
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
...(headers ?? {})
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
+
});
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
return data;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
28
32
|
};
|
|
29
33
|
};
|
|
30
34
|
|
package/data/server/list.ts
CHANGED
|
@@ -16,19 +16,29 @@ const getListDataHandler = (
|
|
|
16
16
|
return async function () {
|
|
17
17
|
const params = generateCommerceSearchParams(searchParams);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
let rawData: string;
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
rawData = await appFetch<string>({
|
|
23
|
+
url: `${category.list}${params}`,
|
|
24
|
+
locale,
|
|
25
|
+
currency,
|
|
26
|
+
init: {
|
|
27
|
+
headers: {
|
|
28
|
+
Accept: 'application/json',
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
...(headers ?? {})
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
responseType: FetchResponseType.TEXT
|
|
34
|
+
});
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.error('Failed to fetch list data', {
|
|
37
|
+
handler: 'getListDataHandler',
|
|
38
|
+
error: error.message
|
|
39
|
+
});
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
32
42
|
|
|
33
43
|
let data: GetCategoryResponse;
|
|
34
44
|
|