@akinon/next 1.108.0-rc.87 → 1.108.0-snapshot-ZERO-3875-occasion-20251229071759

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.
@@ -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
 
@@ -1,7 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { cookies } from 'next/headers';
3
2
  import Settings from 'settings';
4
- import { ServerVariables } from '../utils/server-variables';
5
3
 
6
4
  export async function GET(request: NextRequest) {
7
5
  try {
@@ -9,12 +7,6 @@ export async function GET(request: NextRequest) {
9
7
  const dynamicFilter = request.headers.get('x-search-dynamic-filter');
10
8
  const dynamicExclude = request.headers.get('x-search-dynamic-exclude');
11
9
 
12
- const nextCookies = cookies();
13
- const currency =
14
- nextCookies.get('pz-currency')?.value || ServerVariables.currency;
15
- const locale =
16
- nextCookies.get('pz-locale')?.value || ServerVariables.locale;
17
-
18
10
  if (!dynamicFilter && !dynamicExclude) {
19
11
  return NextResponse.json(
20
12
  {
@@ -48,19 +40,6 @@ export async function GET(request: NextRequest) {
48
40
  headers['x-search-dynamic-exclude'] = dynamicExclude;
49
41
  }
50
42
 
51
- if (currency) {
52
- headers['x-currency'] = currency;
53
- }
54
-
55
- if (locale) {
56
- const currentLocale = Settings.localization.locales.find(
57
- (l) => l.value === locale
58
- );
59
- if (currentLocale) {
60
- headers['Accept-Language'] = currentLocale.apiValue;
61
- }
62
- }
63
-
64
43
  const response = await fetch(apiUrl, {
65
44
  method: 'GET',
66
45
  headers
@@ -12,7 +12,6 @@ export async function GET(request: Request) {
12
12
  const limit = searchParams.get('limit') || '20';
13
13
  const url = searchParams.get('url');
14
14
  const excludedProductIds = searchParams.get('excluded_product_ids');
15
- const text = searchParams.get('text');
16
15
 
17
16
  if (!url) {
18
17
  return errorResponse('URL parameter is required', 400);
@@ -30,10 +29,6 @@ export async function GET(request: Request) {
30
29
  apiParams.append('excluded_product_ids', excludedProductIds);
31
30
  }
32
31
 
33
- if (text) {
34
- apiParams.append('text', text);
35
- }
36
-
37
32
  const apiUrl = `${IMAGE_SEARCH_API_URL}?${apiParams.toString()}`;
38
33
 
39
34
  try {
@@ -90,10 +85,6 @@ export async function POST(request: Request) {
90
85
  bodyData.excluded_product_ids = requestBody.excluded_product_ids;
91
86
  }
92
87
 
93
- if (requestBody.text) {
94
- bodyData.text = requestBody.text;
95
- }
96
-
97
88
  try {
98
89
  const response = await fetch(apiUrl, {
99
90
  method: 'POST',
@@ -0,0 +1,306 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import Settings from 'settings';
3
+
4
+ const VIRTUAL_TRY_ON_API_URL = process.env.NEXT_PUBLIC_VIRTUAL_TRY_ON_API_URL;
5
+
6
+ let limitedCategoriesCache: {
7
+ data: any;
8
+ timestamp: number;
9
+ } | null = null;
10
+
11
+ const CACHE_TTL = 3600000;
12
+
13
+ function getClientIP(request: NextRequest): string | null {
14
+ const forwardedFor = request.headers.get('x-forwarded-for');
15
+ if (forwardedFor) {
16
+ const ip = forwardedFor.split(',')[0].trim();
17
+ if (ip === '::1' || ip === '::ffff:127.0.0.1') {
18
+ return '127.0.0.1';
19
+ }
20
+ return ip;
21
+ }
22
+
23
+ const realIP = request.headers.get('x-real-ip');
24
+ if (realIP) {
25
+ if (realIP === '::1' || realIP === '::ffff:127.0.0.1') {
26
+ return '127.0.0.1';
27
+ }
28
+ return realIP;
29
+ }
30
+
31
+ if (process.env.NODE_ENV === 'development') {
32
+ return '127.0.0.1';
33
+ }
34
+
35
+ return null;
36
+ }
37
+
38
+ function getLocaleFromRequest(request: NextRequest): string | null {
39
+ const cookieLocale = request.cookies.get('pz-locale')?.value;
40
+
41
+ if (cookieLocale) {
42
+ const currentLocale = Settings.localization.locales.find(
43
+ (l) => l.value === cookieLocale
44
+ );
45
+ return currentLocale?.apiValue || null;
46
+ }
47
+
48
+ return null;
49
+ }
50
+
51
+ export async function GET(request: NextRequest) {
52
+ try {
53
+ const { searchParams } = new URL(request.url);
54
+ const endpoint = searchParams.get('endpoint');
55
+
56
+ if (endpoint === 'limited-categories') {
57
+ const now = Date.now();
58
+
59
+ if (
60
+ limitedCategoriesCache &&
61
+ now - limitedCategoriesCache.timestamp < CACHE_TTL
62
+ ) {
63
+ return NextResponse.json(limitedCategoriesCache.data, {
64
+ status: 200,
65
+ headers: {
66
+ 'Access-Control-Allow-Origin': '*',
67
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
68
+ 'Access-Control-Allow-Headers':
69
+ 'Content-Type, Accept, Authorization',
70
+ 'Cache-Control':
71
+ 'public, s-maxage=3600, stale-while-revalidate=7200',
72
+ 'X-Virtual-Try-On-Cache-Status': 'HIT'
73
+ }
74
+ });
75
+ }
76
+
77
+ const externalUrl = `${VIRTUAL_TRY_ON_API_URL}/api/v1/limited-categories`;
78
+ const clientIP = getClientIP(request);
79
+ const locale = getLocaleFromRequest(request);
80
+
81
+ const headersToSend = {
82
+ Accept: 'application/json',
83
+ ...(locale && { 'Accept-Language': locale }),
84
+ ...(request.headers.get('authorization') && {
85
+ Authorization: request.headers.get('authorization')!
86
+ }),
87
+ ...(clientIP && {
88
+ 'X-Forwarded-For': clientIP
89
+ })
90
+ };
91
+
92
+ const response = await fetch(externalUrl, {
93
+ method: 'GET',
94
+ headers: headersToSend
95
+ });
96
+
97
+ let responseData: any;
98
+ const responseText = await response.text();
99
+
100
+ try {
101
+ responseData = responseText ? JSON.parse(responseText) : {};
102
+ } catch (parseError) {
103
+ responseData = { category_ids: [] };
104
+ }
105
+
106
+ if (!response.ok) {
107
+ responseData = { category_ids: [] };
108
+ }
109
+
110
+ limitedCategoriesCache = {
111
+ data: responseData,
112
+ timestamp: Date.now()
113
+ };
114
+
115
+ return NextResponse.json(responseData, {
116
+ status: response.ok ? response.status : 200,
117
+ headers: {
118
+ 'Access-Control-Allow-Origin': '*',
119
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
120
+ 'Access-Control-Allow-Headers': 'Content-Type, Accept, Authorization',
121
+ 'Cache-Control': 'public, s-maxage=3600, stale-while-revalidate=7200',
122
+ 'X-Virtual-Try-On-Cache-Status': 'MISS'
123
+ }
124
+ });
125
+ }
126
+
127
+ return NextResponse.json(
128
+ { error: 'Invalid endpoint for GET method' },
129
+ { status: 400 }
130
+ );
131
+ } catch (error) {
132
+ return NextResponse.json({ category_ids: [] }, { status: 200 });
133
+ }
134
+ }
135
+
136
+ export async function POST(request: NextRequest) {
137
+ try {
138
+ const { searchParams } = new URL(request.url);
139
+ const endpoint = searchParams.get('endpoint');
140
+
141
+ const body = await request.json();
142
+
143
+ let externalUrl: string;
144
+ if (endpoint === 'feedback') {
145
+ externalUrl = `${VIRTUAL_TRY_ON_API_URL}/api/v1/feedback`;
146
+ } else {
147
+ externalUrl = `${VIRTUAL_TRY_ON_API_URL}/api/v1/virtual-try-on`;
148
+ }
149
+
150
+ const httpMethod = endpoint === 'feedback' ? 'PUT' : 'POST';
151
+ const clientIP = getClientIP(request);
152
+ const locale = getLocaleFromRequest(request);
153
+
154
+ const headersToSend = {
155
+ 'Content-Type': 'application/json',
156
+ ...(locale && { 'Accept-Language': locale }),
157
+ ...(httpMethod === 'POST' && { Accept: 'application/json' }),
158
+ ...(request.headers.get('authorization') && {
159
+ Authorization: request.headers.get('authorization')!
160
+ }),
161
+ ...(clientIP && {
162
+ 'X-Forwarded-For': clientIP
163
+ })
164
+ };
165
+
166
+ const response = await fetch(externalUrl, {
167
+ method: httpMethod,
168
+ headers: headersToSend,
169
+ body: JSON.stringify(body)
170
+ });
171
+
172
+ let responseData: any;
173
+ const responseText = await response.text();
174
+
175
+ if (endpoint === 'feedback') {
176
+ try {
177
+ responseData = responseText ? JSON.parse(responseText) : {};
178
+ } catch (parseError) {
179
+ responseData = { error: 'Invalid JSON response from feedback API' };
180
+ }
181
+ } else {
182
+ try {
183
+ responseData = responseText ? JSON.parse(responseText) : {};
184
+ } catch (parseError) {
185
+ responseData = { error: 'Invalid JSON response' };
186
+ }
187
+ }
188
+
189
+ if (!response.ok && responseData.error) {
190
+ let userFriendlyMessage = responseData.error;
191
+
192
+ if (
193
+ typeof responseData.error === 'string' &&
194
+ (responseData.error.includes('duplicate key value') ||
195
+ responseData.error.includes('image_pk'))
196
+ ) {
197
+ userFriendlyMessage =
198
+ 'This image has already been processed. Please try with a different image.';
199
+ } else if (responseData.error.includes('bulk insert images')) {
200
+ userFriendlyMessage =
201
+ 'There was an issue processing your image. Please try again with a different image.';
202
+ }
203
+
204
+ return NextResponse.json(
205
+ {
206
+ ...responseData,
207
+ message: userFriendlyMessage
208
+ },
209
+ {
210
+ status: response.status,
211
+ headers: {
212
+ 'Access-Control-Allow-Origin': '*',
213
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
214
+ 'Access-Control-Allow-Headers':
215
+ 'Content-Type, Accept, Authorization'
216
+ }
217
+ }
218
+ );
219
+ }
220
+
221
+ return NextResponse.json(responseData, {
222
+ status: response.status,
223
+ headers: {
224
+ 'Access-Control-Allow-Origin': '*',
225
+ 'Access-Control-Allow-Methods': 'POST, OPTIONS',
226
+ 'Access-Control-Allow-Headers': 'Content-Type, Accept, Authorization'
227
+ }
228
+ });
229
+ } catch (error) {
230
+ return NextResponse.json(
231
+ {
232
+ status: 'error',
233
+ message:
234
+ 'Internal server error occurred during virtual try-on processing'
235
+ },
236
+ { status: 500 }
237
+ );
238
+ }
239
+ }
240
+
241
+ export async function PUT(request: NextRequest) {
242
+ try {
243
+ const { searchParams } = new URL(request.url);
244
+ const endpoint = searchParams.get('endpoint');
245
+
246
+ if (endpoint !== 'feedback') {
247
+ return NextResponse.json(
248
+ { error: 'PUT method only supports feedback endpoint' },
249
+ { status: 400 }
250
+ );
251
+ }
252
+
253
+ const body = await request.json();
254
+
255
+ const externalUrl = `${VIRTUAL_TRY_ON_API_URL}/api/v1/feedback`;
256
+ const clientIP = getClientIP(request);
257
+ const locale = getLocaleFromRequest(request);
258
+
259
+ const headersToSend = {
260
+ 'Content-Type': 'application/json',
261
+ ...(locale && { 'Accept-Language': locale }),
262
+ ...(request.headers.get('authorization') && {
263
+ Authorization: request.headers.get('authorization')!
264
+ }),
265
+ ...(clientIP && {
266
+ 'X-Forwarded-For': clientIP
267
+ })
268
+ };
269
+
270
+ const response = await fetch(externalUrl, {
271
+ method: 'PUT',
272
+ headers: headersToSend,
273
+ body: JSON.stringify(body)
274
+ });
275
+
276
+ const responseData = await response.json();
277
+
278
+ return NextResponse.json(responseData, {
279
+ status: response.status,
280
+ headers: {
281
+ 'Access-Control-Allow-Origin': '*',
282
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
283
+ 'Access-Control-Allow-Headers': 'Content-Type, Accept, Authorization'
284
+ }
285
+ });
286
+ } catch (error) {
287
+ return NextResponse.json(
288
+ {
289
+ status: 'error',
290
+ message: 'Internal server error occurred during feedback submission'
291
+ },
292
+ { status: 500 }
293
+ );
294
+ }
295
+ }
296
+
297
+ export async function OPTIONS() {
298
+ return new NextResponse(null, {
299
+ status: 200,
300
+ headers: {
301
+ 'Access-Control-Allow-Origin': '*',
302
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS',
303
+ 'Access-Control-Allow-Headers': 'Content-Type, Accept, Authorization'
304
+ }
305
+ });
306
+ }
@@ -2,7 +2,6 @@
2
2
 
3
3
  const runScript = require('./run-script');
4
4
 
5
- runScript('pz-run-tests.js');
6
5
  runScript('pz-install-theme.js');
7
6
  runScript('pz-pre-check-dist.js');
8
7
  runScript('pz-generate-translations.js');
@@ -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 (
@@ -21,8 +21,10 @@ enum Plugin {
21
21
  Akifast = 'pz-akifast',
22
22
  MultiBasket = 'pz-multi-basket',
23
23
  SavedCard = 'pz-saved-card',
24
+ FlowPayment = 'pz-flow-payment',
25
+ VirtualTryOn = 'pz-virtual-try-on',
24
26
  Hepsipay = 'pz-hepsipay',
25
- FlowPayment = 'pz-flow-payment'
27
+ SimilarProducts = 'pz-similar-products'
26
28
  }
27
29
 
28
30
  export enum Component {
@@ -48,6 +50,14 @@ export enum Component {
48
50
  AkifastCheckoutButton = 'CheckoutButton',
49
51
  MultiBasket = 'MultiBasket',
50
52
  SavedCard = 'SavedCardOption',
53
+ VirtualTryOnPlugin = 'VirtualTryOnPlugin',
54
+ SimilarProductsModal = 'SimilarProductsModal',
55
+ SimilarProductsFilterSidebar = 'SimilarProductsFilterSidebar',
56
+ SimilarProductsResultsGrid = 'SimilarProductsResultsGrid',
57
+ SimilarProductsPlugin = 'SimilarProductsPlugin',
58
+ ProductImageSearchFeature = 'ProductImageSearchFeature',
59
+ ImageSearchButton = 'ImageSearchButton',
60
+ HeaderImageSearchFeature = 'HeaderImageSearchFeature',
51
61
  IyzicoSavedCard = 'IyzicoSavedCardOption',
52
62
  Hepsipay = 'Hepsipay',
53
63
  FlowPayment = 'FlowPayment'
@@ -83,10 +93,24 @@ const PluginComponents = new Map([
83
93
  [Component.AkifastQuickLoginButton, Component.AkifastCheckoutButton]
84
94
  ],
85
95
  [Plugin.MultiBasket, [Component.MultiBasket]],
96
+ [Plugin.SavedCard, [Component.SavedCard]],
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
+ ],
86
109
  [Plugin.SavedCard, [Component.SavedCard, Component.IyzicoSavedCard]],
87
110
  [Plugin.SavedCard, [Component.SavedCard]],
88
- [Plugin.Hepsipay, [Component.Hepsipay]],
89
- [Plugin.FlowPayment, [Component.FlowPayment]]
111
+ [Plugin.FlowPayment, [Component.FlowPayment]],
112
+ [Plugin.VirtualTryOn, [Component.VirtualTryOnPlugin]],
113
+ [Plugin.Hepsipay, [Component.Hepsipay]]
90
114
  ]);
91
115
 
92
116
  const getPlugin = (component: Component) => {
@@ -151,10 +175,14 @@ export default function PluginModule({
151
175
  promise = import(`${'@akinon/pz-multi-basket'}`);
152
176
  } else if (plugin === Plugin.SavedCard) {
153
177
  promise = import(`${'@akinon/pz-saved-card'}`);
178
+ } else if (plugin === Plugin.SimilarProducts) {
179
+ promise = import(`${'@akinon/pz-similar-products'}`);
154
180
  } else if (plugin === Plugin.Hepsipay) {
155
181
  promise = import(`${'@akinon/pz-hepsipay'}`);
156
182
  } else if (plugin === Plugin.FlowPayment) {
157
183
  promise = import(`${'@akinon/pz-flow-payment'}`);
184
+ } else if (plugin === Plugin.VirtualTryOn) {
185
+ promise = import(`${'@akinon/pz-virtual-try-on'}`);
158
186
  }
159
187
  } catch (error) {
160
188
  logger.error(error);
@@ -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;
@@ -499,12 +497,22 @@ export const checkoutApi = api.injectEndpoints({
499
497
  dispatch(setPaymentStepBusy(false));
500
498
  }
501
499
  }),
502
- setWalletCompletePage: build.mutation<CheckoutResponse, boolean>({
503
- query: (success: boolean) => ({
504
- url: buildClientRequestUrl(checkout.setWalletCompletePage),
500
+ setWalletCompletePage: build.mutation<
501
+ CheckoutResponse,
502
+ {
503
+ success: boolean;
504
+ cko_payment_id?: string;
505
+ [key: string]: any;
506
+ }
507
+ >({
508
+ query: ({ success, ...additionalParams }) => ({
509
+ url: buildClientRequestUrl(checkout.setWalletCompletePage, {
510
+ useFormData: true
511
+ }),
505
512
  method: 'POST',
506
513
  body: {
507
- success
514
+ success,
515
+ ...additionalParams
508
516
  }
509
517
  }),
510
518
  async onQueryStarted(arg, { dispatch, queryFulfilled }) {
@@ -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
 
@@ -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
  };
@@ -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