@akinon/projectzero 1.59.0 → 1.60.0-rc.6
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 +37 -0
- package/app-template/.gitignore +4 -0
- package/app-template/CHANGELOG.md +2265 -72
- package/app-template/package.json +18 -19
- package/app-template/public/locales/en/account.json +4 -4
- package/app-template/public/locales/tr/account.json +1 -1
- package/app-template/src/app/[commerce]/[locale]/[currency]/[...prettyurl]/page.tsx +8 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/coupons/page.tsx +4 -4
- package/app-template/src/app/[commerce]/[locale]/[currency]/account/profile/page.tsx +1 -0
- package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/page.tsx +5 -2
- package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/page.tsx +12 -8
- package/app-template/src/components/checkbox.tsx +2 -2
- package/app-template/src/components/input.tsx +19 -7
- package/app-template/src/components/pagination.tsx +13 -18
- package/app-template/src/components/price.tsx +9 -4
- package/app-template/src/plugins.js +2 -1
- package/app-template/src/redux/reducers/category.ts +7 -1
- package/app-template/src/settings.js +6 -1
- package/app-template/src/types/index.ts +1 -0
- package/app-template/src/views/account/address-form.tsx +12 -2
- package/app-template/src/views/account/favourite-products/favourite-products-list.tsx +5 -1
- package/app-template/src/views/breadcrumb.tsx +4 -1
- package/app-template/src/views/category/category-active-filters.tsx +16 -6
- package/app-template/src/views/category/category-info.tsx +31 -17
- package/app-template/src/views/category/filters/filter-item.tsx +163 -0
- package/app-template/src/views/category/filters/index.tsx +16 -108
- package/app-template/src/views/category/layout.tsx +5 -3
- package/app-template/src/views/checkout/steps/payment/options/redirection.tsx +43 -37
- package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +19 -3
- package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +230 -34
- package/app-template/src/views/header/mobile-menu.tsx +25 -8
- package/app-template/tsconfig.json +14 -4
- package/dist/commands/plugins.js +4 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projectzeronext",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.60.0-rc.6",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|
|
@@ -22,26 +22,25 @@
|
|
|
22
22
|
"prestart": "pz-prestart"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@akinon/next": "1.
|
|
26
|
-
"@akinon/pz-akifast": "1.
|
|
27
|
-
"@akinon/pz-b2b": "1.
|
|
28
|
-
"@akinon/pz-basket-gift-pack": "1.
|
|
29
|
-
"@akinon/pz-bkm": "1.
|
|
30
|
-
"@akinon/pz-checkout-gift-pack": "1.
|
|
31
|
-
"@akinon/pz-click-collect": "1.
|
|
32
|
-
"@akinon/pz-credit-payment": "1.
|
|
33
|
-
"@akinon/pz-gpay": "1.
|
|
34
|
-
"@akinon/pz-masterpass": "1.
|
|
35
|
-
"@akinon/pz-one-click-checkout": "1.
|
|
36
|
-
"@akinon/pz-otp": "1.
|
|
37
|
-
"@akinon/pz-pay-on-delivery": "1.
|
|
38
|
-
"@akinon/pz-tabby-extension": "1.
|
|
25
|
+
"@akinon/next": "1.60.0-rc.6",
|
|
26
|
+
"@akinon/pz-akifast": "1.60.0-rc.6",
|
|
27
|
+
"@akinon/pz-b2b": "1.60.0-rc.6",
|
|
28
|
+
"@akinon/pz-basket-gift-pack": "1.60.0-rc.6",
|
|
29
|
+
"@akinon/pz-bkm": "1.60.0-rc.6",
|
|
30
|
+
"@akinon/pz-checkout-gift-pack": "1.60.0-rc.6",
|
|
31
|
+
"@akinon/pz-click-collect": "1.60.0-rc.6",
|
|
32
|
+
"@akinon/pz-credit-payment": "1.60.0-rc.6",
|
|
33
|
+
"@akinon/pz-gpay": "1.60.0-rc.6",
|
|
34
|
+
"@akinon/pz-masterpass": "1.60.0-rc.6",
|
|
35
|
+
"@akinon/pz-one-click-checkout": "1.60.0-rc.6",
|
|
36
|
+
"@akinon/pz-otp": "1.60.0-rc.6",
|
|
37
|
+
"@akinon/pz-pay-on-delivery": "1.60.0-rc.6",
|
|
38
|
+
"@akinon/pz-tabby-extension": "1.60.0-rc.6",
|
|
39
39
|
"@hookform/resolvers": "2.9.0",
|
|
40
40
|
"@next/third-parties": "14.1.0",
|
|
41
41
|
"@react-google-maps/api": "2.17.1",
|
|
42
42
|
"@sentry/nextjs": "7.116.0",
|
|
43
43
|
"dayjs": "1.11.5",
|
|
44
|
-
"eslint-config-next": "14.2.2",
|
|
45
44
|
"lossless-json": "2.0.5",
|
|
46
45
|
"next": "14.2.5",
|
|
47
46
|
"next-auth": "4.24.5",
|
|
@@ -60,7 +59,7 @@
|
|
|
60
59
|
"yup": "0.32.11"
|
|
61
60
|
},
|
|
62
61
|
"devDependencies": {
|
|
63
|
-
"@akinon/eslint-plugin-projectzero": "1.
|
|
62
|
+
"@akinon/eslint-plugin-projectzero": "1.60.0-rc.6",
|
|
64
63
|
"@semantic-release/changelog": "6.0.2",
|
|
65
64
|
"@semantic-release/exec": "6.0.3",
|
|
66
65
|
"@semantic-release/git": "10.0.1",
|
|
@@ -80,14 +79,14 @@
|
|
|
80
79
|
"clsx": "1.1.1",
|
|
81
80
|
"currency-symbol-map": "5.1.0",
|
|
82
81
|
"eslint": "8.14.0",
|
|
83
|
-
"eslint-config-next": "14.
|
|
82
|
+
"eslint-config-next": "14.2.3",
|
|
84
83
|
"eslint-config-prettier": "8.5.0",
|
|
85
84
|
"husky": "8.0.0",
|
|
86
85
|
"jest": "29.7.0",
|
|
87
86
|
"jest-css-modules-transform": "4.3.0",
|
|
88
87
|
"lint-staged": "13.1.0",
|
|
89
88
|
"prettier": "2.6.2",
|
|
90
|
-
"react-number-format": "
|
|
89
|
+
"react-number-format": "5.3.4",
|
|
91
90
|
"sass": "1.49.9",
|
|
92
91
|
"semantic-release": "19.0.5",
|
|
93
92
|
"server-only": "0.0.1",
|
|
@@ -286,11 +286,11 @@
|
|
|
286
286
|
"empty_coupon": "You don't have any coupons"
|
|
287
287
|
},
|
|
288
288
|
"title": {
|
|
289
|
-
"
|
|
289
|
+
"campaigns": {
|
|
290
290
|
"active": "Active Campaigns",
|
|
291
|
-
"to_be_active": "
|
|
292
|
-
"expired": "Expired
|
|
293
|
-
"used": "Used
|
|
291
|
+
"to_be_active": "Campaigns to be Active",
|
|
292
|
+
"expired": "Expired Campaigns",
|
|
293
|
+
"used": "Used Campaigns"
|
|
294
294
|
},
|
|
295
295
|
"coupons": {
|
|
296
296
|
"active": "Active Coupons",
|
|
@@ -51,7 +51,7 @@ export default function Page() {
|
|
|
51
51
|
{basketOffersLoading && <LoaderSpinner className="mb-8" />}
|
|
52
52
|
{basketOffersSuccess && (
|
|
53
53
|
<CouponItem
|
|
54
|
-
mainTitle={t('account.my_vouchers.title.
|
|
54
|
+
mainTitle={t('account.my_vouchers.title.campaigns.active')}
|
|
55
55
|
subTitles={[
|
|
56
56
|
t('account.my_vouchers.card.campaign_name'),
|
|
57
57
|
t('account.my_vouchers.card.starting_date'),
|
|
@@ -68,7 +68,7 @@ export default function Page() {
|
|
|
68
68
|
{futureBasketOffersLoading && <LoaderSpinner className="mb-8" />}
|
|
69
69
|
{futureBasketOffersSuccess && (
|
|
70
70
|
<CouponItem
|
|
71
|
-
mainTitle={t('account.my_vouchers.title.
|
|
71
|
+
mainTitle={t('account.my_vouchers.title.campaigns.to_be_active')}
|
|
72
72
|
subTitles={[
|
|
73
73
|
t('account.my_vouchers.card.campaign_name'),
|
|
74
74
|
t('account.my_vouchers.card.starting_date'),
|
|
@@ -85,7 +85,7 @@ export default function Page() {
|
|
|
85
85
|
{expiredBasketOffersLoading && <LoaderSpinner className="mb-8" />}
|
|
86
86
|
{expiredBasketOffersSuccess && (
|
|
87
87
|
<CouponItem
|
|
88
|
-
mainTitle={t('account.my_vouchers.title.
|
|
88
|
+
mainTitle={t('account.my_vouchers.title.campaigns.expired')}
|
|
89
89
|
subTitles={[
|
|
90
90
|
t('account.my_vouchers.card.campaign_name'),
|
|
91
91
|
t('account.my_vouchers.card.starting_date'),
|
|
@@ -102,7 +102,7 @@ export default function Page() {
|
|
|
102
102
|
{discountItemsLoading && <LoaderSpinner className="mb-8" />}
|
|
103
103
|
{discountItemsSuccess && (
|
|
104
104
|
<CouponItem
|
|
105
|
-
mainTitle={t('account.my_vouchers.title.
|
|
105
|
+
mainTitle={t('account.my_vouchers.title.campaigns.used')}
|
|
106
106
|
subTitles={[
|
|
107
107
|
t('account.my_vouchers.card.campaign_name'),
|
|
108
108
|
t('account.my_vouchers.card.starting_date'),
|
|
@@ -4,11 +4,14 @@ import { PageProps } from '@akinon/next/types';
|
|
|
4
4
|
import CategoryLayout from '@theme/views/category/layout';
|
|
5
5
|
|
|
6
6
|
async function Page({ params, searchParams }: PageProps<{ pk: number }>) {
|
|
7
|
-
const { data } = await getCategoryData({
|
|
7
|
+
const { data, breadcrumbData } = await getCategoryData({
|
|
8
|
+
pk: params.pk,
|
|
9
|
+
searchParams
|
|
10
|
+
});
|
|
8
11
|
|
|
9
12
|
return (
|
|
10
13
|
<>
|
|
11
|
-
<CategoryLayout data={data} />
|
|
14
|
+
<CategoryLayout data={data} breadcrumbData={breadcrumbData} />
|
|
12
15
|
</>
|
|
13
16
|
);
|
|
14
17
|
}
|
package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/page.tsx
CHANGED
|
@@ -182,21 +182,25 @@ const CheckoutCompleted = ({
|
|
|
182
182
|
}}
|
|
183
183
|
>
|
|
184
184
|
{data.order.orderitem_set.map((item) => (
|
|
185
|
-
<div
|
|
186
|
-
|
|
185
|
+
<div
|
|
186
|
+
key={`order-item-${item.id}`}
|
|
187
|
+
className="flex justify-between gap-x-4 w-full"
|
|
188
|
+
>
|
|
189
|
+
<Link
|
|
190
|
+
className="flex justify-between gap-x-4 flex-1 items-center transition-all text-xs text-black-800 hover:text-secondary"
|
|
191
|
+
href={item.product.absolute_url}
|
|
192
|
+
passHref
|
|
193
|
+
>
|
|
187
194
|
<Image
|
|
188
195
|
src={item.product.image}
|
|
189
196
|
alt={item.product.name}
|
|
190
197
|
width={64}
|
|
191
198
|
height={96}
|
|
192
199
|
/>
|
|
200
|
+
|
|
201
|
+
<span>{item.product.name}</span>
|
|
193
202
|
</Link>
|
|
194
|
-
<div className="flex justify-
|
|
195
|
-
<>
|
|
196
|
-
<div className="text-xs text-black-800 transition-all w-full hover:text-secondary">
|
|
197
|
-
{item.product.name}
|
|
198
|
-
</div>
|
|
199
|
-
</>
|
|
203
|
+
<div className="flex justify-end items-center">
|
|
200
204
|
<div>
|
|
201
205
|
{item.retail_price !== item.price && (
|
|
202
206
|
<div className="text-black-800 line-through text-xs min-w-max sm:text-sm">
|
|
@@ -3,7 +3,7 @@ import { CheckboxProps } from '@theme/components/types';
|
|
|
3
3
|
import { twMerge } from 'tailwind-merge';
|
|
4
4
|
|
|
5
5
|
const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
|
|
6
|
-
const { children, checked, error, ...rest } = props;
|
|
6
|
+
const { children, checked = false, error, ...rest } = props;
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
<label className={twMerge('flex flex-col text-xs', props.className)}>
|
|
@@ -12,7 +12,7 @@ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => {
|
|
|
12
12
|
type="checkbox"
|
|
13
13
|
{...rest}
|
|
14
14
|
ref={ref}
|
|
15
|
-
|
|
15
|
+
defaultChecked={checked}
|
|
16
16
|
className="w-4 h-4 shrink-0"
|
|
17
17
|
/>
|
|
18
18
|
{children && <span className="ml-2">{children}</span>}
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import { forwardRef, FocusEvent, useState } from 'react';
|
|
2
|
+
import { forwardRef, FocusEvent, useState, Ref } from 'react';
|
|
3
3
|
import { Controller } from 'react-hook-form';
|
|
4
|
-
import
|
|
4
|
+
import { PatternFormat, PatternFormatProps } from 'react-number-format';
|
|
5
5
|
import { InputProps } from '@theme/components/types';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
|
|
8
|
+
const PatternFormatWithRef = forwardRef(
|
|
9
|
+
(props: PatternFormatProps, ref: Ref<HTMLInputElement>) => {
|
|
10
|
+
return <PatternFormat {...props} getInputRef={ref} />;
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
PatternFormatWithRef.displayName = 'PatternFormatWithRef';
|
|
14
|
+
|
|
8
15
|
export const Input = forwardRef<
|
|
9
16
|
HTMLInputElement,
|
|
10
17
|
InputProps &
|
|
11
18
|
Pick<
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
>
|
|
19
|
+
PatternFormatProps,
|
|
20
|
+
'mask' | 'allowEmptyFormatting' | 'onValueChange'
|
|
21
|
+
> & {
|
|
22
|
+
format?: string;
|
|
23
|
+
defaultValue?: string;
|
|
24
|
+
type?: string;
|
|
25
|
+
}
|
|
15
26
|
>((props, ref) => {
|
|
16
27
|
const [focused, setFocused] = useState(false);
|
|
17
28
|
const [hasValue, setHasValue] = useState(false);
|
|
@@ -36,6 +47,7 @@ export const Input = forwardRef<
|
|
|
36
47
|
),
|
|
37
48
|
props.className
|
|
38
49
|
);
|
|
50
|
+
|
|
39
51
|
const inputProps: any = {
|
|
40
52
|
id,
|
|
41
53
|
ref,
|
|
@@ -78,14 +90,14 @@ export const Input = forwardRef<
|
|
|
78
90
|
<Controller
|
|
79
91
|
name={props.name ?? ''}
|
|
80
92
|
control={props.control}
|
|
81
|
-
defaultValue={false}
|
|
82
93
|
render={({ field }) => (
|
|
83
|
-
<
|
|
94
|
+
<PatternFormatWithRef
|
|
84
95
|
format={format}
|
|
85
96
|
mask={mask ?? ''}
|
|
86
97
|
{...rest}
|
|
87
98
|
{...field}
|
|
88
99
|
{...inputProps}
|
|
100
|
+
type={props.type as 'text' | 'password' | 'tel'}
|
|
89
101
|
/>
|
|
90
102
|
)}
|
|
91
103
|
/>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { PaginationProps } from '@theme/components/types';
|
|
3
3
|
import { twMerge } from 'tailwind-merge';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import {
|
|
5
|
+
import { Button } from '@theme/components';
|
|
6
6
|
import usePagination from '@akinon/next/hooks/use-pagination';
|
|
7
7
|
import { useLocalization } from '@akinon/next/hooks';
|
|
8
8
|
import { useRouter } from '@akinon/next/hooks';
|
|
@@ -92,9 +92,7 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
92
92
|
}
|
|
93
93
|
}, [numberOfPages, page, pageList, threshold]);
|
|
94
94
|
|
|
95
|
-
const handleClick = (
|
|
96
|
-
e.preventDefault();
|
|
97
|
-
|
|
95
|
+
const handleClick = (url: string) => {
|
|
98
96
|
const newUrl = new URL(url, window.location.origin);
|
|
99
97
|
const page = newUrl.searchParams.get('page');
|
|
100
98
|
|
|
@@ -129,7 +127,7 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
129
127
|
if (type === 'list') {
|
|
130
128
|
createListItems();
|
|
131
129
|
}
|
|
132
|
-
}, []);
|
|
130
|
+
}, [createListItems, type]);
|
|
133
131
|
|
|
134
132
|
useEffect(() => {
|
|
135
133
|
if (total && total !== paginationTotal) {
|
|
@@ -200,9 +198,8 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
200
198
|
>
|
|
201
199
|
{prev && currentPage !== 1 && (
|
|
202
200
|
<li>
|
|
203
|
-
<
|
|
204
|
-
onClick={(
|
|
205
|
-
href={prev}
|
|
201
|
+
<button
|
|
202
|
+
onClick={() => handleClick(prev)}
|
|
206
203
|
className={twMerge(
|
|
207
204
|
'flex cursor-pointer text-sm px-2',
|
|
208
205
|
prevClassName
|
|
@@ -212,16 +209,15 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
212
209
|
<span className="hidden lg:inline-block ms-4">
|
|
213
210
|
{t('category.pagination.previous')}
|
|
214
211
|
</span>
|
|
215
|
-
</
|
|
212
|
+
</button>
|
|
216
213
|
</li>
|
|
217
214
|
)}
|
|
218
215
|
|
|
219
216
|
{paginationItems.map((item, i) => (
|
|
220
217
|
<li key={i}>
|
|
221
218
|
{item?.url != '#' ? (
|
|
222
|
-
<
|
|
223
|
-
onClick={(
|
|
224
|
-
href={item.url}
|
|
219
|
+
<button
|
|
220
|
+
onClick={() => handleClick(item.url)}
|
|
225
221
|
className={twMerge(
|
|
226
222
|
clsx(
|
|
227
223
|
'text-xs px-2 cursor-pointer',
|
|
@@ -234,7 +230,7 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
234
230
|
)}
|
|
235
231
|
>
|
|
236
232
|
{item?.page}
|
|
237
|
-
</
|
|
233
|
+
</button>
|
|
238
234
|
) : (
|
|
239
235
|
<span className="cursor-default text-xs flex items-center justify-center">
|
|
240
236
|
{item?.page}
|
|
@@ -245,9 +241,8 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
245
241
|
|
|
246
242
|
{showNext && (
|
|
247
243
|
<li>
|
|
248
|
-
<
|
|
249
|
-
onClick={(
|
|
250
|
-
href={next}
|
|
244
|
+
<button
|
|
245
|
+
onClick={() => handleClick(next)}
|
|
251
246
|
className={twMerge(
|
|
252
247
|
'flex cursor-pointer text-xs px-2',
|
|
253
248
|
nextClassName
|
|
@@ -257,7 +252,7 @@ export const Pagination = (props: PaginationProps) => {
|
|
|
257
252
|
{t('category.pagination.next')}
|
|
258
253
|
</span>
|
|
259
254
|
<span>></span>
|
|
260
|
-
</
|
|
255
|
+
</button>
|
|
261
256
|
</li>
|
|
262
257
|
)}
|
|
263
258
|
</ul>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { NumericFormat, NumericFormatProps } from 'react-number-format';
|
|
3
3
|
import { getCurrency } from '@akinon/next/utils';
|
|
4
4
|
import { PriceProps } from '@theme/types';
|
|
5
5
|
import { useLocalization } from '@akinon/next/hooks';
|
|
6
|
+
import Settings from '@theme/settings';
|
|
6
7
|
|
|
7
|
-
export const Price = (props:
|
|
8
|
+
export const Price = (props: NumericFormatProps & PriceProps) => {
|
|
8
9
|
const {
|
|
9
10
|
value,
|
|
10
11
|
currencyCode,
|
|
@@ -37,15 +38,19 @@ export const Price = (props: NumberFormatProps & PriceProps) => {
|
|
|
37
38
|
[currencyCode_, useCurrencySymbol, useCurrencyAfterPrice, useCurrencySpace]
|
|
38
39
|
);
|
|
39
40
|
|
|
41
|
+
const currentCurrencyDecimalScale = Settings.localization.currencies.find(
|
|
42
|
+
(currency) => currency.code === currencyCode_
|
|
43
|
+
).decimalScale;
|
|
44
|
+
|
|
40
45
|
return (
|
|
41
|
-
<
|
|
46
|
+
<NumericFormat
|
|
42
47
|
value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
|
|
43
48
|
{...{
|
|
44
49
|
[useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
|
|
45
50
|
}}
|
|
46
51
|
displayType={displayType}
|
|
47
52
|
thousandSeparator={thousandSeparator}
|
|
48
|
-
decimalScale={decimalScale}
|
|
53
|
+
decimalScale={currentCurrencyDecimalScale ?? decimalScale}
|
|
49
54
|
decimalSeparator={decimalSeparator}
|
|
50
55
|
fixedDecimalScale={fixedDecimalScale}
|
|
51
56
|
{...rest}
|
|
@@ -7,11 +7,13 @@ import { WIDGET_TYPE } from '@theme/types';
|
|
|
7
7
|
export interface CategoryState {
|
|
8
8
|
facets: Facet[];
|
|
9
9
|
selectedFacets: Facet[];
|
|
10
|
+
isMenuOpen: boolean;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const initialState: CategoryState = {
|
|
13
14
|
facets: [],
|
|
14
|
-
selectedFacets: []
|
|
15
|
+
selectedFacets: [],
|
|
16
|
+
isMenuOpen: false
|
|
15
17
|
};
|
|
16
18
|
|
|
17
19
|
const categorySlice = createSlice({
|
|
@@ -24,6 +26,9 @@ const categorySlice = createSlice({
|
|
|
24
26
|
setSelectedFacets(state, action) {
|
|
25
27
|
state.selectedFacets = action.payload;
|
|
26
28
|
},
|
|
29
|
+
setMenuOpen(state, action) {
|
|
30
|
+
state.isMenuOpen = action.payload;
|
|
31
|
+
},
|
|
27
32
|
toggleFacet(state, action) {
|
|
28
33
|
const facets = JSON.parse(JSON.stringify(state.facets));
|
|
29
34
|
|
|
@@ -81,6 +86,7 @@ const categorySlice = createSlice({
|
|
|
81
86
|
export const {
|
|
82
87
|
setFacets,
|
|
83
88
|
setSelectedFacets,
|
|
89
|
+
setMenuOpen,
|
|
84
90
|
toggleFacet,
|
|
85
91
|
removeCategoryFacet,
|
|
86
92
|
resetSelectedFacets
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const { LocaleUrlStrategy } = require('@akinon/next/localization');
|
|
2
2
|
const { ROUTES } = require('@theme/routes');
|
|
3
3
|
|
|
4
|
+
/* IMPORTANT *
|
|
5
|
+
* In order to use one locale in the locales array and hide the default locale in the URL, you need to set the localeUrlStrategy to LocaleUrlStrategy.ShowAllLocales.
|
|
6
|
+
*/
|
|
7
|
+
|
|
4
8
|
const commerceUrl = encodeURI(process.env.SERVICE_BACKEND_URL ?? 'default');
|
|
5
9
|
|
|
6
10
|
/** @type {import('@akinon/next/types').Settings} */
|
|
@@ -11,6 +15,7 @@ module.exports = {
|
|
|
11
15
|
{ translationKey: 'size', key: 'size' }
|
|
12
16
|
],
|
|
13
17
|
localization: {
|
|
18
|
+
// If there is one locale in the locales array, the default locale will be hidden in the URL.
|
|
14
19
|
locales: [
|
|
15
20
|
{
|
|
16
21
|
label: 'EN',
|
|
@@ -38,7 +43,7 @@ module.exports = {
|
|
|
38
43
|
}
|
|
39
44
|
],
|
|
40
45
|
defaultLocaleValue: 'en',
|
|
41
|
-
localeUrlStrategy: LocaleUrlStrategy.HideDefaultLocale,
|
|
46
|
+
localeUrlStrategy: LocaleUrlStrategy.HideDefaultLocale, // If there is one locale in the locales array, the default locale will be hidden in the URL and localeUrlStrategy should be set to LocaleUrlStrategy.ShowAllLocales.
|
|
42
47
|
redirectToDefaultLocale: true,
|
|
43
48
|
defaultCurrencyCode: 'usd'
|
|
44
49
|
},
|
|
@@ -183,12 +183,22 @@ export const AddressForm = (props: Props) => {
|
|
|
183
183
|
if (data && country) {
|
|
184
184
|
reset({
|
|
185
185
|
...data,
|
|
186
|
-
is_corporate:
|
|
187
|
-
String(data.is_corporate) === AddressType.company ? 'true' : 'false' // TODO: Fix this! This hack for radio buttons can't be set to boolean value
|
|
186
|
+
is_corporate: String(data.is_corporate)
|
|
188
187
|
});
|
|
189
188
|
}
|
|
190
189
|
}, [data, country, reset]);
|
|
191
190
|
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (selectedFormType !== AddressType.company) {
|
|
193
|
+
reset({
|
|
194
|
+
...watch(),
|
|
195
|
+
company_name: '',
|
|
196
|
+
tax_office: '',
|
|
197
|
+
tax_no: ''
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}, [selectedFormType, reset, watch]);
|
|
201
|
+
|
|
192
202
|
return (
|
|
193
203
|
<form
|
|
194
204
|
onSubmit={handleSubmit(onSubmit)}
|
|
@@ -30,7 +30,11 @@ const FavoriteProductsList = () => {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (isLoading || isFetching) {
|
|
33
|
-
return
|
|
33
|
+
return (
|
|
34
|
+
<div className="flex items-center justify-center h-80">
|
|
35
|
+
<LoaderSpinner />
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
return (
|
|
@@ -5,6 +5,7 @@ import { Icon, Link } from '@theme/components';
|
|
|
5
5
|
import { ROUTES } from '@theme/routes';
|
|
6
6
|
import { useLocalization } from '@akinon/next/hooks';
|
|
7
7
|
import { BreadcrumbResultType } from '@akinon/next/types';
|
|
8
|
+
import { capitalize } from '@akinon/next/utils';
|
|
8
9
|
|
|
9
10
|
export interface BreadcrumbProps {
|
|
10
11
|
breadcrumbList?: BreadcrumbResultType[];
|
|
@@ -26,7 +27,9 @@ export default function Breadcrumb(props: BreadcrumbProps) {
|
|
|
26
27
|
<div className="flex items-center gap-3 text-xs leading-4 text-gray-950">
|
|
27
28
|
{list.map((item, index) => (
|
|
28
29
|
<Fragment key={index}>
|
|
29
|
-
<Link href={item.url}>
|
|
30
|
+
<Link href={item.url}>
|
|
31
|
+
{capitalize(item.text.toLocaleLowerCase())}
|
|
32
|
+
</Link>
|
|
30
33
|
{index !== list.length - 1 && <Icon name="chevron-end" size={8} />}
|
|
31
34
|
</Fragment>
|
|
32
35
|
))}
|
|
@@ -22,17 +22,28 @@ const CategoryActiveFilters = () => {
|
|
|
22
22
|
const handleRemoveFilter = ({ facet, choice }) => {
|
|
23
23
|
if (facet.widget_type === WIDGET_TYPE.category) {
|
|
24
24
|
dispatch(removeCategoryFacet({ facet, choice }));
|
|
25
|
-
|
|
25
|
+
} else {
|
|
26
|
+
dispatch(toggleFacet({ facet, choice }));
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
const urlSearchParams = new URLSearchParams(window.location.search);
|
|
30
|
+
urlSearchParams.delete(facet.search_key);
|
|
31
|
+
router.replace(pathname + '?' + urlSearchParams.toString());
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
const url = useMemo(() => {
|
|
32
|
-
const facetSearchParams =
|
|
33
|
-
|
|
35
|
+
const facetSearchParams = convertFacetSearchParams(selectedFacets);
|
|
36
|
+
const urlSearchParams = new URLSearchParams(searchParams.toString());
|
|
34
37
|
|
|
35
|
-
const
|
|
38
|
+
for (const key of Array.from(urlSearchParams.keys())) {
|
|
39
|
+
if (facetSearchParams.has(key)) {
|
|
40
|
+
urlSearchParams.delete(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const [key, value] of Array.from(facetSearchParams.entries())) {
|
|
45
|
+
urlSearchParams.append(key, value);
|
|
46
|
+
}
|
|
36
47
|
|
|
37
48
|
const searchText = searchParams.get('search_text');
|
|
38
49
|
const page = searchParams.get('page');
|
|
@@ -53,7 +64,6 @@ const CategoryActiveFilters = () => {
|
|
|
53
64
|
|
|
54
65
|
useEffect(() => {
|
|
55
66
|
router.push(url);
|
|
56
|
-
|
|
57
67
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
68
|
}, [url]);
|
|
59
69
|
|