@akinon/next 1.108.0-rc.87 → 1.108.0-rc.9
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 +74 -1297
- package/__tests__/next-config.test.ts +10 -1
- package/api/similar-product-list.ts +0 -21
- package/api/similar-products.ts +0 -9
- package/api/virtual-try-on.ts +306 -0
- package/bin/pz-prebuild.js +0 -1
- package/components/input.tsx +0 -2
- package/components/link.tsx +12 -16
- package/components/plugin-module.tsx +31 -3
- package/data/client/checkout.ts +16 -8
- package/data/server/category.ts +24 -44
- package/data/server/flatpage.ts +12 -16
- package/data/server/landingpage.ts +12 -16
- package/data/server/list.ts +13 -23
- package/data/server/special-page.ts +12 -16
- package/hocs/server/with-segment-defaults.tsx +2 -5
- package/hooks/use-localization.ts +3 -2
- package/middlewares/complete-gpay.ts +1 -2
- package/middlewares/complete-masterpass.ts +1 -2
- package/middlewares/locale.ts +1 -9
- package/middlewares/redirection-payment.ts +1 -2
- package/middlewares/saved-card-redirection.ts +1 -2
- package/middlewares/three-d-redirection.ts +1 -2
- package/package.json +2 -2
- package/plugins.d.ts +10 -8
- package/plugins.js +3 -1
- package/redux/middlewares/checkout.ts +1 -5
- package/types/commerce/order.ts +0 -1
- package/utils/app-fetch.ts +2 -7
- package/utils/mobile-3d-iframe.ts +8 -2
- package/utils/redirect.ts +3 -18
- package/utils/redirection-iframe.ts +8 -2
- package/__tests__/redirect.test.ts +0 -319
- package/data/server/basket.ts +0 -72
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { resolve } from 'path';
|
|
2
2
|
import type { NextConfig } from 'next';
|
|
3
|
-
|
|
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
|
package/api/similar-products.ts
CHANGED
|
@@ -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
|
+
}
|
package/bin/pz-prebuild.js
CHANGED
package/components/input.tsx
CHANGED
|
@@ -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';
|
package/components/link.tsx
CHANGED
|
@@ -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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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.
|
|
89
|
-
[Plugin.
|
|
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);
|
package/data/client/checkout.ts
CHANGED
|
@@ -35,10 +35,8 @@ import {
|
|
|
35
35
|
|
|
36
36
|
interface CheckoutResponse {
|
|
37
37
|
pre_order?: PreOrder;
|
|
38
|
-
errors
|
|
39
|
-
non_field_errors
|
|
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<
|
|
503
|
-
|
|
504
|
-
|
|
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 }) {
|
package/data/server/category.ts
CHANGED
|
@@ -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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
headers
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
}
|
|
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
|
};
|
package/data/server/flatpage.ts
CHANGED
|
@@ -11,24 +11,20 @@ const getFlatPageDataHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
27
|
+
return data;
|
|
32
28
|
};
|
|
33
29
|
};
|
|
34
30
|
|