@akinon/next 1.93.0-rc.49 → 1.93.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +36 -1260
  2. package/__tests__/next-config.test.ts +10 -1
  3. package/bin/pz-prebuild.js +1 -0
  4. package/components/accordion.tsx +5 -20
  5. package/components/file-input.tsx +3 -65
  6. package/components/input.tsx +0 -2
  7. package/components/link.tsx +12 -16
  8. package/components/modal.tsx +16 -32
  9. package/components/plugin-module.tsx +3 -35
  10. package/components/selected-payment-option-view.tsx +0 -11
  11. package/data/client/checkout.ts +4 -25
  12. package/data/server/category.ts +28 -48
  13. package/data/server/flatpage.ts +12 -16
  14. package/data/server/landingpage.ts +12 -16
  15. package/data/server/list.ts +13 -23
  16. package/data/server/product.ts +39 -66
  17. package/data/server/special-page.ts +12 -16
  18. package/data/urls.ts +2 -7
  19. package/hocs/server/with-segment-defaults.tsx +2 -5
  20. package/hooks/use-localization.ts +3 -2
  21. package/instrumentation/node.ts +13 -15
  22. package/jest.config.js +1 -7
  23. package/lib/cache.ts +0 -2
  24. package/middlewares/checkout-provider.ts +1 -1
  25. package/middlewares/complete-gpay.ts +2 -6
  26. package/middlewares/complete-masterpass.ts +2 -7
  27. package/middlewares/default.ts +183 -232
  28. package/middlewares/index.ts +1 -3
  29. package/middlewares/locale.ts +1 -9
  30. package/middlewares/redirection-payment.ts +2 -6
  31. package/middlewares/saved-card-redirection.ts +2 -7
  32. package/middlewares/three-d-redirection.ts +2 -7
  33. package/middlewares/url-redirection.ts +15 -9
  34. package/package.json +3 -3
  35. package/plugins.d.ts +0 -10
  36. package/plugins.js +1 -4
  37. package/redux/middlewares/checkout.ts +2 -15
  38. package/redux/reducers/checkout.ts +1 -9
  39. package/sentry/index.ts +17 -54
  40. package/types/commerce/order.ts +0 -1
  41. package/types/index.ts +1 -42
  42. package/utils/app-fetch.ts +2 -7
  43. package/utils/index.ts +10 -34
  44. package/utils/redirect.ts +6 -31
  45. package/with-pz-config.js +5 -1
  46. package/__tests__/redirect.test.ts +0 -758
  47. package/api/image-proxy.ts +0 -75
  48. package/api/similar-product-list.ts +0 -84
  49. package/api/similar-products.ts +0 -120
  50. package/data/server/basket.ts +0 -72
  51. package/hooks/use-loyalty-availability.ts +0 -21
  52. package/middlewares/wallet-complete-redirection.ts +0 -203
  53. package/utils/redirect-ignore.ts +0 -35
@@ -1,6 +1,15 @@
1
1
  import { resolve } from 'path';
2
2
  import type { NextConfig } from 'next';
3
- const findBaseDir = require('../utils/find-base-dir');
3
+
4
+ function findBaseDir() {
5
+ const insideNodeModules = __dirname.includes('node_modules');
6
+
7
+ if (insideNodeModules) {
8
+ return resolve(__dirname, '../../../../');
9
+ } else {
10
+ return resolve(__dirname, '../../../apps/projectzeronext');
11
+ }
12
+ }
4
13
 
5
14
  const baseDir = findBaseDir();
6
15
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  const runScript = require('./run-script');
4
4
 
5
+ runScript('pz-run-tests.js');
5
6
  runScript('pz-install-theme.js');
6
7
  runScript('pz-pre-check-dist.js');
7
8
  runScript('pz-generate-translations.js');
@@ -7,19 +7,15 @@ import { AccordionProps } from '../types';
7
7
 
8
8
  export const Accordion = ({
9
9
  isCollapse = false,
10
- collapseClassName,
11
10
  title,
12
11
  subTitle,
13
12
  icons = ['chevron-up', 'chevron-down'],
14
13
  iconSize = 16,
15
14
  iconColor = 'fill-[#000000]',
16
15
  children,
17
- headerClassName,
18
16
  className,
19
17
  titleClassName,
20
- subTitleClassName,
21
- dataTestId,
22
- contentClassName
18
+ dataTestId
23
19
  }: AccordionProps) => {
24
20
  const [collapse, setCollapse] = useState(isCollapse);
25
21
 
@@ -31,22 +27,15 @@ export const Accordion = ({
31
27
  )}
32
28
  >
33
29
  <div
34
- className={twMerge(
35
- 'flex items-center justify-between cursor-pointer',
36
- headerClassName
37
- )}
30
+ className="flex items-center justify-between cursor-pointer"
38
31
  onClick={() => setCollapse(!collapse)}
39
32
  data-testid={dataTestId}
40
33
  >
41
- <div className={twMerge('flex flex-col', contentClassName)}>
34
+ <div className="flex flex-col">
42
35
  {title && (
43
36
  <h3 className={twMerge('text-sm', titleClassName)}>{title}</h3>
44
37
  )}
45
- {subTitle && (
46
- <h4 className={twMerge('text-xs text-gray-700', subTitleClassName)}>
47
- {subTitle}
48
- </h4>
49
- )}
38
+ {subTitle && <h4 className="text-xs text-gray-700">{subTitle}</h4>}
50
39
  </div>
51
40
 
52
41
  {icons && (
@@ -57,11 +46,7 @@ export const Accordion = ({
57
46
  />
58
47
  )}
59
48
  </div>
60
- {collapse && (
61
- <div className={twMerge('mt-3 text-sm', collapseClassName)}>
62
- {children}
63
- </div>
64
- )}
49
+ {collapse && <div className="mt-3 text-sm">{children}</div>}
65
50
  </div>
66
51
  );
67
52
  };
@@ -1,70 +1,8 @@
1
- import { useState } from 'react';
2
1
  import { forwardRef } from 'react';
3
- import { useLocalization } from '@akinon/next/hooks';
4
- import { twMerge } from 'tailwind-merge';
5
- import { FileInputProps } from '../types';
2
+ import { FileInputProps } from '../types/index';
6
3
 
7
4
  export const FileInput = forwardRef<HTMLInputElement, FileInputProps>(
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
- );
5
+ function fileInput(props, ref) {
6
+ return <input type="file" {...props} ref={ref} />;
69
7
  }
70
8
  );
@@ -1,8 +1,6 @@
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
6
4
  import { PatternFormat, PatternFormatProps } from 'react-number-format';
7
5
  import { InputProps } from '../types';
8
6
  import { twMerge } from 'tailwind-merge';
@@ -10,9 +10,7 @@ type LinkProps = Omit<
10
10
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
11
11
  keyof NextLinkProps
12
12
  > &
13
- NextLinkProps & {
14
- href: string;
15
- };
13
+ NextLinkProps;
16
14
 
17
15
  export const Link = ({ children, href, ...rest }: LinkProps) => {
18
16
  const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
@@ -28,21 +26,19 @@ export const Link = ({ children, href, ...rest }: LinkProps) => {
28
26
  return href;
29
27
  }
30
28
 
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
- }
29
+ const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
30
+ const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
31
+
32
+ if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
33
+ return hrefWithLocale;
34
+ } else if (
35
+ localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
36
+ locale !== defaultLocaleValue
37
+ ) {
38
+ return hrefWithLocale;
43
39
  }
44
40
 
45
- return href;
41
+ return href || '#';
46
42
  }, [href, defaultLocaleValue, locale, localeUrlStrategy]);
47
43
 
48
44
  return (
@@ -4,7 +4,16 @@ 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
- import { ModalProps } from '../types';
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
+ }
8
17
 
9
18
  export const Modal = (props: ModalProps) => {
10
19
  const {
@@ -14,14 +23,7 @@ export const Modal = (props: ModalProps) => {
14
23
  setOpen,
15
24
  title = '',
16
25
  showCloseButton = true,
17
- className,
18
- overlayClassName,
19
- headerWrapperClassName,
20
- titleClassName,
21
- closeButtonClassName,
22
- iconName = 'close',
23
- iconSize = 16,
24
- iconClassName
26
+ className
25
27
  } = props;
26
28
 
27
29
  useEffect(() => {
@@ -36,12 +38,7 @@ export const Modal = (props: ModalProps) => {
36
38
 
37
39
  return (
38
40
  <ReactPortal wrapperId={portalId}>
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
- />
41
+ <div className="fixed top-0 left-0 w-screen h-screen bg-primary bg-opacity-60 z-50" />
45
42
  <section
46
43
  className={twMerge(
47
44
  'fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-50 bg-white',
@@ -49,28 +46,15 @@ export const Modal = (props: ModalProps) => {
49
46
  )}
50
47
  >
51
48
  {(showCloseButton || title) && (
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
- )}
49
+ <div className="flex px-6 py-4 border-b border-gray-400">
50
+ {title && <h3 className="text-lg font-light">{title}</h3>}
63
51
  {showCloseButton && (
64
52
  <button
65
53
  type="button"
66
54
  onClick={() => setOpen(false)}
67
- className={twMerge('ml-auto', closeButtonClassName)}
55
+ className="ml-auto"
68
56
  >
69
- <Icon
70
- name={iconName}
71
- size={iconSize}
72
- className={iconClassName}
73
- />
57
+ <Icon name="close" size={16} />
74
58
  </button>
75
59
  )}
76
60
  </div>
@@ -20,10 +20,7 @@ enum Plugin {
20
20
  B2B = 'pz-b2b',
21
21
  Akifast = 'pz-akifast',
22
22
  MultiBasket = 'pz-multi-basket',
23
- SavedCard = 'pz-saved-card',
24
- Hepsipay = 'pz-hepsipay',
25
- FlowPayment = 'pz-flow-payment',
26
- SimilarProducts = 'pz-similar-products'
23
+ SavedCard = 'pz-saved-card'
27
24
  }
28
25
 
29
26
  export enum Component {
@@ -48,16 +45,7 @@ export enum Component {
48
45
  AkifastQuickLoginButton = 'QuickLoginButton',
49
46
  AkifastCheckoutButton = 'CheckoutButton',
50
47
  MultiBasket = 'MultiBasket',
51
- SavedCard = 'SavedCardOption',
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'
48
+ SavedCard = 'SavedCardOption'
61
49
  }
62
50
 
63
51
  const PluginComponents = new Map([
@@ -90,21 +78,7 @@ const PluginComponents = new Map([
90
78
  [Component.AkifastQuickLoginButton, Component.AkifastCheckoutButton]
91
79
  ],
92
80
  [Plugin.MultiBasket, [Component.MultiBasket]],
93
- [Plugin.SavedCard, [Component.SavedCard]],
94
- [Plugin.Hepsipay, [Component.Hepsipay]],
95
- [Plugin.FlowPayment, [Component.FlowPayment]],
96
- [
97
- Plugin.SimilarProducts,
98
- [
99
- Component.SimilarProductsModal,
100
- Component.SimilarProductsFilterSidebar,
101
- Component.SimilarProductsResultsGrid,
102
- Component.SimilarProductsPlugin,
103
- Component.ProductImageSearchFeature,
104
- Component.ImageSearchButton,
105
- Component.HeaderImageSearchFeature
106
- ]
107
- ]
81
+ [Plugin.SavedCard, [Component.SavedCard]]
108
82
  ]);
109
83
 
110
84
  const getPlugin = (component: Component) => {
@@ -169,12 +143,6 @@ export default function PluginModule({
169
143
  promise = import(`${'@akinon/pz-multi-basket'}`);
170
144
  } else if (plugin === Plugin.SavedCard) {
171
145
  promise = import(`${'@akinon/pz-saved-card'}`);
172
- } else if (plugin === Plugin.Hepsipay) {
173
- promise = import(`${'@akinon/pz-hepsipay'}`);
174
- } else if (plugin === Plugin.FlowPayment) {
175
- promise = import(`${'@akinon/pz-flow-payment'}`);
176
- } else if (plugin === Plugin.SimilarProducts) {
177
- promise = import(`${'@akinon/pz-similar-products'}`);
178
146
  }
179
147
  } catch (error) {
180
148
  logger.error(error);
@@ -62,17 +62,6 @@ export default function SelectedPaymentOptionView({
62
62
  : fallbackView;
63
63
  }
64
64
 
65
- if (
66
- payment_option?.payment_type === 'wallet' &&
67
- wallet_method === 'checkout_flow'
68
- ) {
69
- const mod = await import('@akinon/pz-flow-payment');
70
-
71
- return typeof mod?.default === 'function'
72
- ? mod.default
73
- : fallbackView;
74
- }
75
-
76
65
  const view = paymentTypeToView[payment_option?.payment_type] || null;
77
66
 
78
67
  if (view) {
@@ -35,10 +35,8 @@ import {
35
35
 
36
36
  interface CheckoutResponse {
37
37
  pre_order?: PreOrder;
38
- errors?: {
39
- non_field_errors?: string;
40
- sample_products?: string[];
41
- [key: string]: string | string[] | undefined;
38
+ errors: {
39
+ non_field_errors: string;
42
40
  };
43
41
  context_list?: CheckoutContext[];
44
42
  template_name?: string;
@@ -183,10 +181,7 @@ export const checkoutApi = api.injectEndpoints({
183
181
  endpoints: (build) => ({
184
182
  fetchCheckout: build.query<CheckoutResponse, void>({
185
183
  query: () => ({
186
- url: buildClientRequestUrl(
187
- `${checkout.fetchCheckout}?page=IndexPage`,
188
- {}
189
- )
184
+ url: buildClientRequestUrl(checkout.fetchCheckout, {})
190
185
  }),
191
186
  providesTags: ['Checkout']
192
187
  }),
@@ -872,21 +867,6 @@ export const checkoutApi = api.injectEndpoints({
872
867
  method: 'POST',
873
868
  body
874
869
  })
875
- }),
876
- saveSampleProducts: build.mutation<CheckoutResponse, number[] | undefined>({
877
- query: (products = []) => {
878
- const formData = new FormData();
879
-
880
- products.forEach((product) => {
881
- formData.append('sample_products', String(product));
882
- });
883
-
884
- return {
885
- url: buildClientRequestUrl(checkout.saveSampleProducts),
886
- method: 'POST',
887
- body: formData
888
- };
889
- }
890
870
  })
891
871
  }),
892
872
  overrideExisting: false
@@ -934,6 +914,5 @@ export const {
934
914
  useSetWalletCompletePageMutation,
935
915
  useSendSmsMutation,
936
916
  useVerifySmsMutation,
937
- useResetCheckoutStateQuery,
938
- useSaveSampleProductsMutation
917
+ useResetCheckoutStateQuery
939
918
  } = checkoutApi;
@@ -5,6 +5,7 @@ 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';
8
9
  import { ServerVariables } from '../../utils/server-variables';
9
10
 
10
11
  function getCategoryDataHandler(
@@ -17,30 +18,19 @@ function getCategoryDataHandler(
17
18
  return async function () {
18
19
  const params = generateCommerceSearchParams(searchParams);
19
20
 
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
- }
21
+ const rawData = await appFetch<string>({
22
+ url: `${category.getCategoryByPk(pk)}${params ? params : ''}`,
23
+ locale,
24
+ currency,
25
+ init: {
26
+ headers: {
27
+ Accept: 'application/json',
28
+ 'Content-Type': 'application/json',
29
+ ...(headers ?? {})
30
+ }
31
+ },
32
+ responseType: FetchResponseType.TEXT
33
+ });
44
34
 
45
35
  let data: GetCategoryResponse;
46
36
 
@@ -58,8 +48,8 @@ function getCategoryDataHandler(
58
48
  logger.fatal('Error while parsing category data', {
59
49
  handler: 'getCategoryDataHandler',
60
50
  error,
61
- rawData: rawData?.startsWith?.('<!DOCTYPE html>')
62
- ? `${rawData?.substring(0, 50)}...`
51
+ rawData: rawData.startsWith('<!DOCTYPE html>')
52
+ ? `${rawData.substring(0, 50)}...`
63
53
  : rawData
64
54
  });
65
55
  }
@@ -74,27 +64,17 @@ function getCategoryDataHandler(
74
64
  return { data, breadcrumbData: undefined };
75
65
  }
76
66
 
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
- }
67
+ const breadcrumbData = await appFetch<any>({
68
+ url: product.breadcrumbUrl(menuItemModel),
69
+ locale,
70
+ currency,
71
+ init: {
72
+ headers: {
73
+ Accept: 'application/json',
74
+ 'Content-Type': 'application/json'
89
75
  }
90
- });
91
- } catch (error) {
92
- logger.warn('Failed to fetch breadcrumb data', {
93
- handler: 'getCategoryDataHandler',
94
- pk,
95
- error: error.message
96
- });
97
- }
76
+ }
77
+ });
98
78
 
99
79
  return { data, breadcrumbData: breadcrumbData?.menu };
100
80
  };
@@ -158,8 +138,8 @@ function getCategoryBySlugDataHandler(
158
138
  logger.fatal('Error while parsing category data', {
159
139
  handler: 'getCategoryBySlugDataHandler',
160
140
  error,
161
- rawData: rawData?.startsWith?.('<!DOCTYPE html>')
162
- ? `${rawData?.substring(0, 50)}...`
141
+ rawData: rawData.startsWith('<!DOCTYPE html>')
142
+ ? `${rawData.substring(0, 50)}...`
163
143
  : rawData
164
144
  });
165
145
  }
@@ -11,24 +11,20 @@ const getFlatPageDataHandler = (
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
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
- }
14
+ const data = await appFetch<FlatPage>({
15
+ url: flatpage.getFlatPageByPk(pk),
16
+ locale,
17
+ currency,
18
+ init: {
19
+ headers: {
20
+ Accept: 'application/json',
21
+ 'Content-Type': 'application/json',
22
+ ...(headers ?? {})
25
23
  }
26
- });
24
+ }
25
+ });
27
26
 
28
- return data;
29
- } catch (error) {
30
- return null;
31
- }
27
+ return data;
32
28
  };
33
29
  };
34
30
 
@@ -11,24 +11,20 @@ const getLandingPageHandler = (
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
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
- }
14
+ const data = await appFetch<LandingPage>({
15
+ url: landingpage.getLandingPageByPk(pk),
16
+ locale,
17
+ currency,
18
+ init: {
19
+ headers: {
20
+ Accept: 'application/json',
21
+ 'Content-Type': 'application/json',
22
+ ...(headers ?? {})
25
23
  }
26
- });
24
+ }
25
+ });
27
26
 
28
- return data;
29
- } catch (error) {
30
- return null;
31
- }
27
+ return data;
32
28
  };
33
29
  };
34
30
 
@@ -16,29 +16,19 @@ const getListDataHandler = (
16
16
  return async function () {
17
17
  const params = generateCommerceSearchParams(searchParams);
18
18
 
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
- }
19
+ const rawData = await appFetch<string>({
20
+ url: `${category.list}${params}`,
21
+ locale,
22
+ currency,
23
+ init: {
24
+ headers: {
25
+ Accept: 'application/json',
26
+ 'Content-Type': 'application/json',
27
+ ...(headers ?? {})
28
+ }
29
+ },
30
+ responseType: FetchResponseType.TEXT
31
+ });
42
32
 
43
33
  let data: GetCategoryResponse;
44
34