@akinon/projectzero 2.0.0-beta.1 → 2.0.0-beta.10
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 +35 -0
- package/app-template/.env.example +5 -0
- package/app-template/.gitignore +2 -0
- package/app-template/CHANGELOG.md +225 -0
- package/app-template/README.md +6 -0
- package/app-template/config/prebuild-tests.json +5 -0
- package/app-template/{next.config.mjs → next.config.ts} +6 -3
- package/app-template/package.json +30 -27
- package/app-template/postcss.config.mjs +8 -0
- package/app-template/public/locales/en/account.json +4 -0
- package/app-template/public/locales/en/common.json +10 -0
- package/app-template/public/locales/tr/account.json +4 -0
- package/app-template/public/locales/tr/common.json +10 -0
- package/app-template/src/__tests__/middleware-matcher.test.ts +135 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/cancellation/page.tsx +93 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/page.tsx +66 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/address/stores/page.tsx +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/auth/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/basket/page.tsx +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/error.tsx +12 -15
- package/app-template/src/app/[commerce]/[locale]/[currency]/forms/[pk]/generate/page.tsx +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/{pz-not-found/page.tsx → not-found.tsx} +2 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx +7 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/xml-sitemap/[node]/route.ts +47 -1
- package/app-template/src/assets/globals.scss +162 -34
- package/app-template/src/components/__tests__/badge.test.tsx +2 -2
- package/app-template/src/components/accordion.tsx +1 -1
- package/app-template/src/components/button.tsx +50 -35
- package/app-template/src/components/file-input.tsx +44 -2
- package/app-template/src/components/input.tsx +3 -3
- package/app-template/src/components/modal.tsx +1 -1
- package/app-template/src/components/select.tsx +2 -2
- package/app-template/src/components/shimmer.tsx +1 -1
- package/app-template/src/components/tabs.tsx +2 -2
- package/app-template/src/components/types/index.ts +4 -1
- package/app-template/src/middleware.ts +1 -0
- package/app-template/src/plugins.js +2 -1
- package/app-template/src/redux/middlewares/category.ts +1 -1
- package/app-template/src/redux/reducers/category.ts +1 -1
- package/app-template/src/redux/store.ts +4 -3
- package/app-template/src/settings.js +1 -2
- package/app-template/src/utils/convert-facet-search-params.ts +1 -1
- package/app-template/src/views/account/contact-form.tsx +3 -8
- package/app-template/src/views/account/content-header.tsx +2 -3
- package/app-template/src/views/account/order.tsx +1 -1
- package/app-template/src/views/account/orders/order-cancellation-item.tsx +5 -4
- package/app-template/src/views/anonymous-tracking/order-detail/index.tsx +1 -1
- package/app-template/src/views/basket/basket-item.tsx +1 -0
- package/app-template/src/views/category/category-active-filters.tsx +1 -1
- package/app-template/src/views/category/category-header.tsx +12 -6
- package/app-template/src/views/category/category-info.tsx +4 -4
- package/app-template/src/views/category/filters/index.tsx +2 -2
- package/app-template/src/views/checkout/auth.tsx +1 -1
- package/app-template/src/views/checkout/layout/header.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/index.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +1 -1
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +4 -4
- package/app-template/src/views/checkout/steps/shipping/address-box.tsx +3 -3
- package/app-template/src/views/checkout/steps/shipping/addresses.tsx +1 -1
- package/app-template/src/views/checkout/summary.tsx +2 -2
- package/app-template/src/views/header/action-menu.tsx +6 -3
- package/app-template/src/views/header/band.tsx +2 -2
- package/app-template/src/views/header/mini-basket.tsx +15 -4
- package/app-template/src/views/header/mobile-menu.tsx +6 -6
- package/app-template/src/views/header/navbar.tsx +1 -1
- package/app-template/src/views/header/pwa-back-button.tsx +1 -1
- package/app-template/src/views/header/search/index.tsx +16 -4
- package/app-template/src/views/header/search/results.tsx +1 -1
- package/app-template/src/views/header/user-menu.tsx +3 -1
- package/app-template/src/views/installment-options/index.tsx +1 -1
- package/app-template/src/views/login/index.tsx +30 -6
- package/app-template/src/views/otp-login/index.tsx +12 -14
- package/app-template/src/views/product/product-info.tsx +2 -2
- package/app-template/src/views/product/slider.tsx +1 -1
- package/app-template/src/views/product-pointer-banner-item.tsx +1 -1
- package/app-template/src/views/register/index.tsx +29 -4
- package/app-template/src/views/sales-contract-modal/index.tsx +17 -17
- package/app-template/src/widgets/footer-info.tsx +1 -1
- package/app-template/src/widgets/footer-menu.tsx +1 -1
- package/app-template/src/widgets/footer-subscription/index.tsx +1 -1
- package/app-template/src/widgets/home-stories-eng.tsx +1 -1
- package/app-template/tailwind.config.js +1 -137
- package/codemods/sentry-9/index.js +30 -0
- package/codemods/sentry-9/remove-sentry-configs.js +14 -0
- package/codemods/sentry-9/remove-sentry-dependency.js +25 -0
- package/codemods/sentry-9/replace-error-page.js +32 -0
- package/commands/codemod.ts +18 -0
- package/commands/index.ts +3 -1
- package/commands/plugins.ts +4 -0
- package/dist/codemods/sentry-9/templates/error.js +14 -0
- package/dist/commands/codemod.js +16 -0
- package/dist/commands/index.js +3 -1
- package/dist/commands/plugins.js +4 -0
- package/package.json +1 -1
- package/app-template/postcss.config.js +0 -6
- package/app-template/sentry.client.config.ts +0 -16
- package/app-template/sentry.edge.config.ts +0 -3
- package/app-template/sentry.properties +0 -4
- package/app-template/sentry.server.config.ts +0 -3
- package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/loading.tsx +0 -67
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
Select,
|
|
16
16
|
Modal,
|
|
17
17
|
LoaderSpinner,
|
|
18
|
-
Link
|
|
18
|
+
Link,
|
|
19
|
+
FileInput
|
|
19
20
|
} from '@theme/components';
|
|
20
21
|
import { useState, use } from 'react';
|
|
21
22
|
import { OrderDetailHeader } from '@theme/views/account/orders/order-detail-header';
|
|
@@ -41,6 +42,7 @@ const AccountOrderCancellation = ({ params }) => {
|
|
|
41
42
|
} = useForm<AccountOrderCancellation>({
|
|
42
43
|
resolver: yupResolver(accountOrderCancellationSchema)
|
|
43
44
|
});
|
|
45
|
+
|
|
44
46
|
const { data: cancellationReasons, isSuccess: cancellationReasonsSuccess } =
|
|
45
47
|
useGetCancellationReasonsQuery();
|
|
46
48
|
|
|
@@ -58,6 +60,9 @@ const AccountOrderCancellation = ({ params }) => {
|
|
|
58
60
|
const watchAllFields = watch();
|
|
59
61
|
const cancelItemsLength = watchAllFields?.cancel_order_items?.length;
|
|
60
62
|
const [cancelOrder] = useCancelOrderMutation();
|
|
63
|
+
const [files, setFiles] = useState<
|
|
64
|
+
{ itemId: string; image: string; description: string }[]
|
|
65
|
+
>([]);
|
|
61
66
|
|
|
62
67
|
const modalHandleClick = () => {
|
|
63
68
|
setIsModalOpen(false);
|
|
@@ -114,8 +119,68 @@ const AccountOrderCancellation = ({ params }) => {
|
|
|
114
119
|
]);
|
|
115
120
|
};
|
|
116
121
|
|
|
122
|
+
const handleFileChange = async (
|
|
123
|
+
e: React.ChangeEvent<HTMLInputElement>,
|
|
124
|
+
itemId: string,
|
|
125
|
+
description: string
|
|
126
|
+
) => {
|
|
127
|
+
const selectedFiles = Array.from(e.target.files || []);
|
|
128
|
+
|
|
129
|
+
const base64Files = await Promise.all(
|
|
130
|
+
selectedFiles.map((file) => {
|
|
131
|
+
return new Promise<string>((resolve, reject) => {
|
|
132
|
+
const reader = new FileReader();
|
|
133
|
+
reader.onload = () => resolve(reader.result as string);
|
|
134
|
+
reader.onerror = reject;
|
|
135
|
+
reader.readAsDataURL(file);
|
|
136
|
+
});
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
const validFiles = base64Files.filter((file) =>
|
|
141
|
+
/^data:image\/(jpeg|png|jpg);base64,.+/.test(file)
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const formattedFiles = validFiles.map((file) => ({
|
|
145
|
+
itemId,
|
|
146
|
+
image: file,
|
|
147
|
+
description
|
|
148
|
+
}));
|
|
149
|
+
|
|
150
|
+
setFiles((prevFiles) => [
|
|
151
|
+
...prevFiles.filter((f) => f.itemId !== itemId),
|
|
152
|
+
...formattedFiles
|
|
153
|
+
]);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const fileInputCondition = (item, description: string) => {
|
|
157
|
+
if (item.is_refundable && !item.active_cancellation_request) {
|
|
158
|
+
return (
|
|
159
|
+
<FileInput
|
|
160
|
+
name="files"
|
|
161
|
+
title="files"
|
|
162
|
+
multiple
|
|
163
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
|
164
|
+
handleFileChange(e, item.id, description)
|
|
165
|
+
}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
117
171
|
const onSubmit: SubmitHandler<AccountOrderCancellation> = (orderItems) => {
|
|
118
|
-
|
|
172
|
+
const mergedData = {
|
|
173
|
+
...orderItems,
|
|
174
|
+
cancel_order_items: orderItems.cancel_order_items.map((orderItem) => ({
|
|
175
|
+
...orderItem,
|
|
176
|
+
...(files.length > 0 && {
|
|
177
|
+
cancellation_request_image_set: files.filter(
|
|
178
|
+
(file) => file.itemId === orderItem.order_item
|
|
179
|
+
)
|
|
180
|
+
})
|
|
181
|
+
}))
|
|
182
|
+
};
|
|
183
|
+
cancelOrder({ id: order.number, ...mergedData })
|
|
119
184
|
.unwrap()
|
|
120
185
|
.then(() => {
|
|
121
186
|
setResponseMessage({
|
|
@@ -124,10 +189,33 @@ const AccountOrderCancellation = ({ params }) => {
|
|
|
124
189
|
});
|
|
125
190
|
setIsModalOpen(true);
|
|
126
191
|
})
|
|
127
|
-
.catch(() => {
|
|
192
|
+
.catch((err) => {
|
|
193
|
+
console.error('Err', err);
|
|
194
|
+
|
|
195
|
+
const errorMessages = new Set();
|
|
196
|
+
|
|
197
|
+
if (err?.data?.cancel_order_items) {
|
|
198
|
+
err.data.cancel_order_items.forEach((item) => {
|
|
199
|
+
if (item.cancellation_request_image_set) {
|
|
200
|
+
item.cancellation_request_image_set.forEach((error) => {
|
|
201
|
+
if (typeof error === 'string') {
|
|
202
|
+
errorMessages.add(error);
|
|
203
|
+
} else if (typeof error === 'object' && error?.image) {
|
|
204
|
+
error.image.forEach((msg) => errorMessages.add(msg));
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const errorContent =
|
|
212
|
+
errorMessages.size > 0
|
|
213
|
+
? Array.from(errorMessages).join('\n')
|
|
214
|
+
: t('account.my_orders.return.error.description').toString();
|
|
215
|
+
|
|
128
216
|
setResponseMessage({
|
|
129
217
|
title: t('account.my_orders.return.error.title').toString(),
|
|
130
|
-
content:
|
|
218
|
+
content: errorContent
|
|
131
219
|
});
|
|
132
220
|
setIsModalOpen(true);
|
|
133
221
|
});
|
|
@@ -182,6 +270,7 @@ const AccountOrderCancellation = ({ params }) => {
|
|
|
182
270
|
onChange={onChange}
|
|
183
271
|
value={value}
|
|
184
272
|
selectOption={selectOption}
|
|
273
|
+
fileInput={fileInputCondition(item, item.product.name)}
|
|
185
274
|
/>
|
|
186
275
|
);
|
|
187
276
|
}}
|
|
@@ -144,7 +144,7 @@ const AccountOrderDetail = ({ params }) => {
|
|
|
144
144
|
key={index}
|
|
145
145
|
>
|
|
146
146
|
<div className="flex gap-3 mb-5 lg:mb-0">
|
|
147
|
-
<div className="
|
|
147
|
+
<div className="shrink-0">
|
|
148
148
|
<Link
|
|
149
149
|
className="block"
|
|
150
150
|
href={item.product.absolute_url}
|
|
@@ -208,8 +208,7 @@ const AccountOrderDetail = ({ params }) => {
|
|
|
208
208
|
</div>
|
|
209
209
|
|
|
210
210
|
{(item.is_cancellable || item.is_refundable) &&
|
|
211
|
-
order.is_cancellable &&
|
|
212
|
-
item.status.value == '400' && (
|
|
211
|
+
order.is_cancellable && (
|
|
213
212
|
<div className="lg:ml-24">
|
|
214
213
|
<Link
|
|
215
214
|
href={`${ROUTES.ACCOUNT_ORDERS}/${order.id}/cancellation`}
|
|
@@ -227,7 +226,6 @@ const AccountOrderDetail = ({ params }) => {
|
|
|
227
226
|
</div>
|
|
228
227
|
)}
|
|
229
228
|
</div>
|
|
230
|
-
|
|
231
229
|
<div className="flex flex-col justify-center items-end lg:ml-6 lg:min-w-[7rem]">
|
|
232
230
|
{parseFloat(item.retail_price) >
|
|
233
231
|
parseFloat(item.price) && (
|
|
@@ -251,6 +249,70 @@ const AccountOrderDetail = ({ params }) => {
|
|
|
251
249
|
);
|
|
252
250
|
})}
|
|
253
251
|
</div>
|
|
252
|
+
|
|
253
|
+
{group.map((item) =>
|
|
254
|
+
item.cancellationrequest_set?.map((cancellationItem) => {
|
|
255
|
+
const status = cancellationItem.status?.value;
|
|
256
|
+
const isRejected = status === 'rejected';
|
|
257
|
+
const isCompleted = status === 'completed';
|
|
258
|
+
|
|
259
|
+
const filteredImages =
|
|
260
|
+
cancellationItem.cancellation_request_image_set?.filter(
|
|
261
|
+
(img) =>
|
|
262
|
+
isRejected
|
|
263
|
+
? !img.is_uploaded_by_user
|
|
264
|
+
: isCompleted
|
|
265
|
+
? img.is_uploaded_by_user
|
|
266
|
+
: false
|
|
267
|
+
) || [];
|
|
268
|
+
|
|
269
|
+
const statusText = isRejected
|
|
270
|
+
? t('account.my_orders.return.rejected')
|
|
271
|
+
: isCompleted
|
|
272
|
+
? t('account.my_orders.return.completed')
|
|
273
|
+
: null;
|
|
274
|
+
|
|
275
|
+
if (!statusText || filteredImages.length === 0) return null;
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<div
|
|
279
|
+
className="w-full px-4 lg:px-7"
|
|
280
|
+
key={cancellationItem.id}
|
|
281
|
+
>
|
|
282
|
+
<div className="flex flex-col py-2 gap-4 border-t border-gray">
|
|
283
|
+
<div className="flex flex-col">
|
|
284
|
+
<div className="text-sm font-semibold">
|
|
285
|
+
{t('account.my_orders.return.return_status')}
|
|
286
|
+
<span className="font-normal"> {statusText}</span>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
<div className="flex gap-2 mt-2 flex-wrap">
|
|
290
|
+
{filteredImages.map((img) => (
|
|
291
|
+
<div className="flex flex-col gap-2" key={img.id}>
|
|
292
|
+
<Link href={img.image} target="_blank">
|
|
293
|
+
<Image
|
|
294
|
+
src={img.image}
|
|
295
|
+
width={112}
|
|
296
|
+
height={150}
|
|
297
|
+
alt={img.description}
|
|
298
|
+
/>
|
|
299
|
+
</Link>
|
|
300
|
+
|
|
301
|
+
{img.description && (
|
|
302
|
+
<p className="text-xs">
|
|
303
|
+
{t('account.my_orders.return.explanation')}:
|
|
304
|
+
{img.description}
|
|
305
|
+
</p>
|
|
306
|
+
)}
|
|
307
|
+
</div>
|
|
308
|
+
))}
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
);
|
|
314
|
+
})
|
|
315
|
+
)}
|
|
254
316
|
</div>
|
|
255
317
|
);
|
|
256
318
|
})}
|
|
@@ -53,7 +53,7 @@ export default function Page() {
|
|
|
53
53
|
<div className="hidden lg:block">
|
|
54
54
|
<div className="bg-gray-150">
|
|
55
55
|
{orderLoading && (
|
|
56
|
-
<SkeletonWrapper className="w-full px-6 mb-12 h-28 items-center justify-center
|
|
56
|
+
<SkeletonWrapper className="w-full px-6 mb-12 h-28 items-center justify-center flex-row! xl:h-[5.5rem]">
|
|
57
57
|
<Skeleton className="w-[11.375rem] h-16 mr-4 xl:w-[16rem] xl:h-10" />
|
|
58
58
|
<Skeleton className="w-56 h-10 mr-4" />
|
|
59
59
|
<Skeleton className="w-[12.75rem] h-10 xl:w-56" />
|
|
@@ -122,7 +122,7 @@ export default function Stores() {
|
|
|
122
122
|
|
|
123
123
|
<div className="flex gap-6 mt-4 flex-col md:flex-row">
|
|
124
124
|
{city && (
|
|
125
|
-
<div className="w-full
|
|
125
|
+
<div className="w-full shrink-0 md:w-60 overflow-y-scroll max-h-[36rem]">
|
|
126
126
|
{cityLoading && (
|
|
127
127
|
<SkeletonWrapper>
|
|
128
128
|
<Skeleton className="w-full h-20" />
|
|
@@ -174,7 +174,7 @@ export default function Stores() {
|
|
|
174
174
|
title={store.name}
|
|
175
175
|
titleClassName="text-xs font-bold"
|
|
176
176
|
iconSize={12}
|
|
177
|
-
className="relative py-3 border-b justify-center mb-0"
|
|
177
|
+
className="relative py-3 border-b border-gray-200 justify-center mb-0"
|
|
178
178
|
>
|
|
179
179
|
<div className="text-xs">
|
|
180
180
|
{store.address && (
|
|
@@ -51,7 +51,7 @@ export default function Auth() {
|
|
|
51
51
|
{t('auth.register.mobile_title')}
|
|
52
52
|
</Button>
|
|
53
53
|
</div>
|
|
54
|
-
<div className="w-full flex flex-wrap border md:border-0">
|
|
54
|
+
<div className="w-full flex flex-wrap border border-gray-200 md:border-0">
|
|
55
55
|
<div
|
|
56
56
|
className={twMerge(
|
|
57
57
|
clsx('w-full md:block md:w-1/2', {
|
|
@@ -25,7 +25,7 @@ export default function Page() {
|
|
|
25
25
|
}, [basket, isSuccess]);
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
|
-
<div className="max-w-
|
|
28
|
+
<div className="max-w-(--breakpoint-xl) p-4 flex flex-col text-primary-800 lg:p-8 xl:flex-row xl:mx-auto">
|
|
29
29
|
{isLoading && (
|
|
30
30
|
<div className="flex justify-center w-full">
|
|
31
31
|
<LoaderSpinner />
|
|
@@ -62,7 +62,7 @@ export default function Page() {
|
|
|
62
62
|
<Summary basket={basket} />
|
|
63
63
|
</>
|
|
64
64
|
) : (
|
|
65
|
-
<div className="flex flex-col items-center container max-w-
|
|
65
|
+
<div className="flex flex-col items-center container max-w-(--breakpoint-sm) py-4 px-4 xs:py-6 xs:px-6 sm:py-8 sm:px-8 lg:max-w-(--breakpoint-xl)">
|
|
66
66
|
<h1
|
|
67
67
|
className="w-full text-xl font-light text-secondary text-center sm:text-2xl"
|
|
68
68
|
data-testid="basket-empty"
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import { ROUTES } from '@theme/routes';
|
|
3
|
+
import { useSentryUncaughtErrors } from '@akinon/next/hooks';
|
|
4
|
+
import PzErrorPage from '@akinon/next/views/error-page';
|
|
6
5
|
|
|
7
|
-
export default function
|
|
8
|
-
|
|
6
|
+
export default function ErrorPage({
|
|
7
|
+
error,
|
|
8
|
+
reset
|
|
9
|
+
}: {
|
|
10
|
+
error: Error & { digest?: string; isServerError?: boolean };
|
|
11
|
+
reset: () => void;
|
|
12
|
+
}) {
|
|
13
|
+
// DO NOT REMOVE THIS LINE TO REPORT UNCAUGHT ERRORS TO SENTRY
|
|
14
|
+
useSentryUncaughtErrors(error);
|
|
9
15
|
|
|
10
|
-
return
|
|
11
|
-
<section className="text-center px-6 my-14 md:px-0 md:m-14">
|
|
12
|
-
<div className="text-7xl font-bold md:text-8xl">500</div>
|
|
13
|
-
<h1 className="text-lg md:text-xl"> {t('common.page_500.title')} </h1>
|
|
14
|
-
<p className="text-lg md:text-xl"> {t('common.page_500.description')} </p>
|
|
15
|
-
<Link href={ROUTES.HOME} className="text-lg underline">
|
|
16
|
-
{t('common.page_500.link_text')}
|
|
17
|
-
</Link>
|
|
18
|
-
</section>
|
|
19
|
-
);
|
|
16
|
+
return <PzErrorPage error={error} reset={reset} />;
|
|
20
17
|
}
|
|
@@ -21,7 +21,7 @@ export default async function Page(props) {
|
|
|
21
21
|
schema={schema}
|
|
22
22
|
allFieldClasses={{
|
|
23
23
|
className:
|
|
24
|
-
'border border-[#d4d4d4] text-[#4a4f54] mt-1.5 h-[38px] p-2.5 text-xs outline-
|
|
24
|
+
'border border-[#d4d4d4] text-[#4a4f54] mt-1.5 h-[38px] p-2.5 text-xs outline-hidden focus:border-black',
|
|
25
25
|
labelClassName: 'text-[#4a4f54] text-xs',
|
|
26
26
|
wrapperClassName: 'flex flex-col mb-6'
|
|
27
27
|
}}
|
package/app-template/src/app/[commerce]/[locale]/[currency]/{pz-not-found/page.tsx → not-found.tsx}
RENAMED
|
@@ -8,10 +8,10 @@ const NotFound = () => {
|
|
|
8
8
|
const { t } = useLocalization();
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
|
-
<div className="py-
|
|
11
|
+
<div className="py-10 lg:py-8 flex flex-col items-center justify-center px-4 lg:px-0">
|
|
12
12
|
<div className="text-8xl font-bold">404</div>
|
|
13
13
|
<h1 className="text-4xl font-bold mb-4">{t('not_found.title')}</h1>
|
|
14
|
-
<p className="text-lg mb-6">{t('not_found.sub_title')}</p>
|
|
14
|
+
<p className="text-lg mb-6 text-center">{t('not_found.sub_title')}</p>
|
|
15
15
|
<Link href={'/'}>
|
|
16
16
|
<Button className="h-auto mt-4 text-base py-3 px-6">
|
|
17
17
|
{t('not_found.button')}
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '@akinon/next/redux/reducers/checkout';
|
|
12
12
|
import { RootState } from '@theme/redux/store';
|
|
13
13
|
import { ROUTES } from '@theme/routes';
|
|
14
|
-
import { useFetchCheckoutQuery } from '@akinon/next/data/client/checkout';
|
|
14
|
+
import { useFetchCheckoutQuery, useResetCheckoutStateQuery } from '@akinon/next/data/client/checkout';
|
|
15
15
|
import { Button, LoaderSpinner } from '@theme/components';
|
|
16
16
|
import { pushAddPaymentInfo, pushAddShippingInfo } from '@theme/utils/gtm';
|
|
17
17
|
import { CheckoutStep } from '@akinon/next/types';
|
|
@@ -25,6 +25,8 @@ const Checkout = () => {
|
|
|
25
25
|
(state: RootState) => state.checkout
|
|
26
26
|
);
|
|
27
27
|
|
|
28
|
+
const { data: indexData, isLoading: isResetStateLoading } = useResetCheckoutStateQuery(null);
|
|
29
|
+
|
|
28
30
|
const {
|
|
29
31
|
data: checkoutData,
|
|
30
32
|
isFetching,
|
|
@@ -32,7 +34,8 @@ const Checkout = () => {
|
|
|
32
34
|
isSuccess,
|
|
33
35
|
refetch: refetchCheckout
|
|
34
36
|
} = useFetchCheckoutQuery(null, {
|
|
35
|
-
refetchOnMountOrArgChange: true
|
|
37
|
+
refetchOnMountOrArgChange: true,
|
|
38
|
+
skip: isResetStateLoading || !indexData
|
|
36
39
|
});
|
|
37
40
|
const initialStepChanged = useRef<boolean>(false);
|
|
38
41
|
const router = useRouter();
|
|
@@ -94,10 +97,10 @@ const Checkout = () => {
|
|
|
94
97
|
);
|
|
95
98
|
}
|
|
96
99
|
|
|
97
|
-
if (isFetching || isError) {
|
|
100
|
+
if (isResetStateLoading || isFetching || isError) {
|
|
98
101
|
return (
|
|
99
102
|
<div className="flex flex-col items-center justify-center h-80">
|
|
100
|
-
{isFetching ? (
|
|
103
|
+
{isResetStateLoading || isFetching ? (
|
|
101
104
|
<LoaderSpinner />
|
|
102
105
|
) : (
|
|
103
106
|
<>
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { urlLocaleMatcherRegex } from '@akinon/next/utils';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* XML Sitemap Route
|
|
5
|
+
*
|
|
6
|
+
* This route serves XML sitemaps from an S3 bucket.
|
|
7
|
+
*
|
|
8
|
+
* Required environment variables:
|
|
9
|
+
* - SITEMAP_S3_BUCKET_NAME: The name of the S3 bucket containing the sitemaps
|
|
10
|
+
* Example: "0fb534"
|
|
11
|
+
*
|
|
12
|
+
* If the environment variable is not set, the route will return a 503 Service Unavailable
|
|
13
|
+
* response with a JSON error message.
|
|
14
|
+
*/
|
|
15
|
+
|
|
3
16
|
export const dynamic = 'force-dynamic';
|
|
4
17
|
|
|
5
18
|
export async function GET(request: Request, context: { params }) {
|
|
@@ -7,9 +20,42 @@ export async function GET(request: Request, context: { params }) {
|
|
|
7
20
|
const url = new URL(request.url);
|
|
8
21
|
const matchedLocale = url.pathname.match(urlLocaleMatcherRegex);
|
|
9
22
|
|
|
23
|
+
const s3BucketName = process.env.SITEMAP_S3_BUCKET_NAME;
|
|
24
|
+
|
|
25
|
+
if (!s3BucketName) {
|
|
26
|
+
return new Response(
|
|
27
|
+
JSON.stringify({
|
|
28
|
+
error: 'Configuration error',
|
|
29
|
+
message: 'Please set the SITEMAP_S3_BUCKET_NAME environment variable'
|
|
30
|
+
}),
|
|
31
|
+
{
|
|
32
|
+
status: 503,
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
10
40
|
const sitemap = await fetch(
|
|
11
|
-
`https://s3.eu-central-1.amazonaws.com/
|
|
41
|
+
`https://s3.eu-central-1.amazonaws.com/${s3BucketName}/sitemaps/sitemaps/sitemap-${node}.xml.gz`
|
|
12
42
|
);
|
|
43
|
+
|
|
44
|
+
if (!sitemap.ok) {
|
|
45
|
+
return new Response(
|
|
46
|
+
JSON.stringify({
|
|
47
|
+
error: 'Sitemap not found',
|
|
48
|
+
message: `Failed to fetch sitemap for node: ${node}`
|
|
49
|
+
}),
|
|
50
|
+
{
|
|
51
|
+
status: 503,
|
|
52
|
+
headers: {
|
|
53
|
+
'Content-Type': 'application/json'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
13
59
|
let sitemapContent = await sitemap.text();
|
|
14
60
|
|
|
15
61
|
sitemapContent = sitemapContent.replace(
|
|
@@ -2,48 +2,176 @@
|
|
|
2
2
|
@use './fonts/index.scss' as fonts;
|
|
3
3
|
@use './fonts/pz-icon.css' as icons;
|
|
4
4
|
|
|
5
|
-
@
|
|
6
|
-
@tailwind components;
|
|
7
|
-
@tailwind utilities;
|
|
8
|
-
|
|
9
|
-
@layer utilities {
|
|
10
|
-
.header-grid-template-areas {
|
|
11
|
-
grid-template-areas:
|
|
12
|
-
'band-l band-m band-r'
|
|
13
|
-
'main-l main-m main-r'
|
|
14
|
-
'nav nav nav';
|
|
15
|
-
}
|
|
5
|
+
@import 'tailwindcss';
|
|
16
6
|
|
|
17
|
-
|
|
18
|
-
grid-area: band-l;
|
|
19
|
-
}
|
|
7
|
+
@plugin '@tailwindcss/typography';
|
|
20
8
|
|
|
21
|
-
|
|
22
|
-
grid-area: band-m;
|
|
23
|
-
}
|
|
9
|
+
@config '../../tailwind.config.js';
|
|
24
10
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
@source '../app/**/*.{js,ts,jsx,tsx}';
|
|
12
|
+
@source '../pages/**/*.{js,ts,jsx,tsx}';
|
|
13
|
+
@source '../components/**/*.{js,ts,jsx,tsx}';
|
|
14
|
+
@source '../views/**/*.{js,ts,jsx,tsx}';
|
|
15
|
+
@source '../widgets/**/*.{js,ts,jsx,tsx}';
|
|
16
|
+
@source '../hooks/**/*.{js,ts,jsx,tsx}';
|
|
17
|
+
@source '../utils/**/*.{js,ts,jsx,tsx}';
|
|
28
18
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
19
|
+
@theme {
|
|
20
|
+
--font-sans: 'Jost', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
|
|
21
|
+
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
|
22
|
+
--font-size-2xs: 0.5rem;
|
|
23
|
+
--outline-off: none;
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
--width-1-10: 10%;
|
|
26
|
+
--width-2-10: 20%;
|
|
27
|
+
--width-3-10: 30%;
|
|
28
|
+
--width-4-10: 40%;
|
|
29
|
+
--width-5-10: 50%;
|
|
30
|
+
--width-6-10: 60%;
|
|
31
|
+
--width-7-10: 70%;
|
|
32
|
+
--width-8-10: 80%;
|
|
33
|
+
--width-9-10: 90%;
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
--transition-property-max-width: max-width;
|
|
36
|
+
|
|
37
|
+
--background-image-skeleton-shimmer: linear-gradient(
|
|
38
|
+
90deg,
|
|
39
|
+
#d7d7d7 0%,
|
|
40
|
+
#ebebeb 40%,
|
|
41
|
+
#eeeeee 60%,
|
|
42
|
+
#d7d7d7
|
|
43
|
+
);
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
--animate-skeleton-shimmer: skeleton-shimmer 2s linear infinite;
|
|
46
|
+
|
|
47
|
+
@keyframes skeleton-shimmer {
|
|
48
|
+
to {
|
|
49
|
+
transform: translateX(100%);
|
|
50
|
+
}
|
|
43
51
|
}
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
--color-transparent: transparent;
|
|
54
|
+
--color-white: #ffffff;
|
|
55
|
+
--color-primary: #000000;
|
|
56
|
+
--color-primary-hover: #181818;
|
|
57
|
+
--color-primary-foreground: #ffffff;
|
|
58
|
+
--color-primary-100: #525252;
|
|
59
|
+
--color-primary-200: #404040;
|
|
60
|
+
--color-primary-300: #3d3d3d;
|
|
61
|
+
--color-primary-400: #333333;
|
|
62
|
+
--color-primary-500: #2d2d2d;
|
|
63
|
+
--color-primary-600: #292929;
|
|
64
|
+
--color-primary-700: #2b2b2b;
|
|
65
|
+
--color-primary-800: #181818;
|
|
66
|
+
--color-primary-900: #000000;
|
|
67
|
+
|
|
68
|
+
--color-secondary: #e95151;
|
|
69
|
+
--color-secondary-hover: #d03838;
|
|
70
|
+
--color-secondary-foreground: #ffffff;
|
|
71
|
+
--color-secondary-100: #ffb7b7;
|
|
72
|
+
--color-secondary-200: #ff9e9e;
|
|
73
|
+
--color-secondary-300: #ff8484;
|
|
74
|
+
--color-secondary-400: #ff6b6b;
|
|
75
|
+
--color-secondary-500: #e95151;
|
|
76
|
+
--color-secondary-600: #d72b01;
|
|
77
|
+
--color-secondary-700: #b61e1e;
|
|
78
|
+
--color-secondary-800: #9d0505;
|
|
79
|
+
--color-secondary-900: #830000;
|
|
80
|
+
|
|
81
|
+
--color-black: #000000;
|
|
82
|
+
--color-black-100: #525252;
|
|
83
|
+
--color-black-200: #404040;
|
|
84
|
+
--color-black-300: #3d3d3d;
|
|
85
|
+
--color-black-400: #333333;
|
|
86
|
+
--color-black-500: #2d2d2d;
|
|
87
|
+
--color-black-600: #292929;
|
|
88
|
+
--color-black-700: #2b2b2b;
|
|
89
|
+
--color-black-800: #181818;
|
|
90
|
+
--color-black-900: #000000;
|
|
91
|
+
|
|
92
|
+
--color-gray: #ebebeb;
|
|
93
|
+
--color-gray-25: #fdfdfd;
|
|
94
|
+
--color-gray-50: #f7f7f7;
|
|
95
|
+
--color-gray-100: #f5f5f5;
|
|
96
|
+
--color-gray-150: #f4f4f4;
|
|
97
|
+
--color-gray-200: #eeeeee;
|
|
98
|
+
--color-gray-300: #ebebeb;
|
|
99
|
+
--color-gray-400: #d7d7d7;
|
|
100
|
+
--color-gray-450: #d4d4d4;
|
|
101
|
+
--color-gray-500: #c9c9c9;
|
|
102
|
+
--color-gray-600: #9d9d9d;
|
|
103
|
+
--color-gray-700: #686868;
|
|
104
|
+
--color-gray-800: #615f62;
|
|
105
|
+
--color-gray-850: #58585a;
|
|
106
|
+
--color-gray-900: #4a4f54;
|
|
107
|
+
--color-gray-950: #424242;
|
|
108
|
+
|
|
109
|
+
--color-error: #d72b01;
|
|
110
|
+
--color-error-100: #e20008;
|
|
111
|
+
|
|
112
|
+
--color-success: #7b9d76;
|
|
113
|
+
--color-success-100: #7b9d76;
|
|
114
|
+
|
|
115
|
+
--container-center: true;
|
|
116
|
+
--container-padding: 0rem;
|
|
117
|
+
--container-padding-sm: 2rem;
|
|
118
|
+
--container-padding-2xl: 0rem;
|
|
119
|
+
|
|
120
|
+
--breakpoint-xs: 575px;
|
|
121
|
+
--breakpoint-sm: 640px;
|
|
122
|
+
--breakpoint-md: 768px;
|
|
123
|
+
--breakpoint-lg: 1024px;
|
|
124
|
+
--breakpoint-xl: 1170px;
|
|
125
|
+
--breakpoint-2xl: 1370px;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@utility header-grid-template-areas {
|
|
129
|
+
grid-template-areas:
|
|
130
|
+
'band-l band-m band-r'
|
|
131
|
+
'main-l main-m main-r'
|
|
132
|
+
'nav nav nav';
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@utility header-grid-area-band-l {
|
|
136
|
+
grid-area: band-l;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@utility header-grid-area-band-m {
|
|
140
|
+
grid-area: band-m;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@utility header-grid-area-band-r {
|
|
144
|
+
grid-area: band-r;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@utility header-grid-area-main-l {
|
|
148
|
+
grid-area: main-l;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
@utility header-grid-area-main-m {
|
|
152
|
+
grid-area: main-m;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@utility header-grid-area-main-r {
|
|
156
|
+
grid-area: main-r;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@utility header-grid-area-nav {
|
|
160
|
+
grid-area: nav;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@utility header-m-template-cols {
|
|
164
|
+
grid-template-columns: auto 1fr 1fr;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@utility container {
|
|
168
|
+
margin-inline: auto;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@layer base {
|
|
172
|
+
input::placeholder,
|
|
173
|
+
textarea::placeholder {
|
|
174
|
+
color: theme(--color-gray-400);
|
|
47
175
|
}
|
|
48
176
|
|
|
49
177
|
input {
|
|
@@ -51,7 +179,7 @@
|
|
|
51
179
|
&:not(:placeholder-shown),
|
|
52
180
|
&:autofill {
|
|
53
181
|
& + label {
|
|
54
|
-
|
|
182
|
+
top: calc(1 / 3 * 100%);
|
|
55
183
|
}
|
|
56
184
|
}
|
|
57
185
|
}
|