@akinon/next 1.17.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/components/index.ts +2 -0
- package/components/link.tsx +52 -0
- package/components/pagination.tsx +194 -0
- package/components/plugin-module.tsx +11 -3
- package/data/client/account.ts +5 -2
- package/data/client/checkout.ts +4 -1
- package/data/urls.ts +4 -2
- package/hooks/index.ts +1 -0
- package/hooks/use-pagination.ts +136 -0
- package/package.json +2 -2
- package/plugins.js +1 -0
- package/types/commerce/product.ts +2 -2
- package/utils/get-currency-label.ts +9 -0
- package/utils/get-currency.ts +4 -2
- package/utils/index.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
+
## 1.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- db017b2c: ZERO-2271: Fix showing currency code instead of label
|
|
8
|
+
- db017b2c: ZERO-2389: Show card logo in credit card form
|
|
9
|
+
- db017b2c: ZERO-2387: Add sorting by date in orders page
|
|
10
|
+
- db017b2c: ZERO-2377: Add B2B plugin
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- db017b2c: ZERO-2417: Update basket_offers type in Product interface
|
|
15
|
+
|
|
16
|
+
## 1.17.1
|
|
17
|
+
|
|
3
18
|
## 1.17.0
|
|
4
19
|
|
|
5
20
|
## 1.16.3
|
package/components/index.ts
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
4
|
+
import { LocaleUrlStrategy } from '@akinon/next/localization';
|
|
5
|
+
import { urlLocaleMatcherRegex } from '@akinon/next/utils';
|
|
6
|
+
import NextLink, { LinkProps as NextLinkProps } from 'next/link';
|
|
7
|
+
import { useEffect, useState } from 'react';
|
|
8
|
+
|
|
9
|
+
interface LinkProps extends NextLinkProps {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const Link = ({
|
|
16
|
+
children,
|
|
17
|
+
target,
|
|
18
|
+
className,
|
|
19
|
+
href,
|
|
20
|
+
...rest
|
|
21
|
+
}: LinkProps) => {
|
|
22
|
+
const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
|
|
23
|
+
const [formattedHref, setFormattedHref] = useState(href ?? '#');
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (typeof href !== 'string') return;
|
|
27
|
+
if (href.startsWith('http')) return;
|
|
28
|
+
|
|
29
|
+
const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
|
|
30
|
+
const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
|
|
31
|
+
|
|
32
|
+
if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
|
|
33
|
+
setFormattedHref(hrefWithLocale);
|
|
34
|
+
} else if (
|
|
35
|
+
localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
|
|
36
|
+
locale !== defaultLocaleValue
|
|
37
|
+
) {
|
|
38
|
+
setFormattedHref(hrefWithLocale);
|
|
39
|
+
}
|
|
40
|
+
}, [href, defaultLocaleValue, locale, localeUrlStrategy]);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<NextLink
|
|
44
|
+
href={formattedHref}
|
|
45
|
+
target={target}
|
|
46
|
+
className={className}
|
|
47
|
+
{...rest}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</NextLink>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { MouseEvent, useCallback, useEffect, useState } from 'react';
|
|
4
|
+
import { PaginationProps } from '@theme/components/types';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import clsx from 'clsx';
|
|
7
|
+
|
|
8
|
+
import usePagination from '@akinon/next/hooks/use-pagination';
|
|
9
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
10
|
+
import { useRouter } from '@akinon/next/hooks';
|
|
11
|
+
import { Link } from './link';
|
|
12
|
+
|
|
13
|
+
export const Pagination = (props: PaginationProps) => {
|
|
14
|
+
const { t } = useLocalization();
|
|
15
|
+
const router = useRouter();
|
|
16
|
+
const {
|
|
17
|
+
total,
|
|
18
|
+
limit,
|
|
19
|
+
currentPage,
|
|
20
|
+
numberOfPages,
|
|
21
|
+
containerClassName,
|
|
22
|
+
prevClassName,
|
|
23
|
+
pageClassName,
|
|
24
|
+
nextClassName,
|
|
25
|
+
threshold = 1,
|
|
26
|
+
render
|
|
27
|
+
} = props;
|
|
28
|
+
|
|
29
|
+
const pagination = usePagination(total, limit, currentPage, numberOfPages);
|
|
30
|
+
const {
|
|
31
|
+
total: paginationTotal,
|
|
32
|
+
limit: paginationLimit,
|
|
33
|
+
page,
|
|
34
|
+
pageList,
|
|
35
|
+
prev,
|
|
36
|
+
next,
|
|
37
|
+
setTotal,
|
|
38
|
+
setLimit
|
|
39
|
+
} = pagination;
|
|
40
|
+
|
|
41
|
+
const [paginationItems, setPaginationItems] = useState([]);
|
|
42
|
+
const showNext = currentPage * paginationLimit < total;
|
|
43
|
+
|
|
44
|
+
const createListItems = useCallback(() => {
|
|
45
|
+
setPaginationItems([]);
|
|
46
|
+
const delta = 2;
|
|
47
|
+
const startPage = Math.max(Number(page) - delta, 1);
|
|
48
|
+
const endPage = Math.min(Number(page) + delta, numberOfPages);
|
|
49
|
+
|
|
50
|
+
setPaginationItems((prev) => [
|
|
51
|
+
...prev,
|
|
52
|
+
{
|
|
53
|
+
page: pageList[0].page,
|
|
54
|
+
url: pageList[0].url
|
|
55
|
+
}
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
if (delta < startPage) {
|
|
59
|
+
setPaginationItems((prev) => [...prev, { page: '...', url: '#' }]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (let i = startPage; i <= endPage; i++) {
|
|
63
|
+
if (i === 1) continue;
|
|
64
|
+
|
|
65
|
+
setPaginationItems((prev) => [
|
|
66
|
+
...prev,
|
|
67
|
+
{
|
|
68
|
+
page: pageList[i - 1]?.page,
|
|
69
|
+
url: pageList[i - 1]?.url
|
|
70
|
+
}
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (endPage < numberOfPages - threshold) {
|
|
75
|
+
setPaginationItems((prev) => [...prev, { page: '...', url: '#' }]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (page < numberOfPages - delta) {
|
|
79
|
+
setPaginationItems((prev) => [
|
|
80
|
+
...prev,
|
|
81
|
+
{
|
|
82
|
+
page: pageList[pageList.length - threshold].page,
|
|
83
|
+
url: pageList[pageList.length - threshold].url
|
|
84
|
+
}
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
87
|
+
}, [numberOfPages, page, pageList, threshold]);
|
|
88
|
+
|
|
89
|
+
const handleClick = (e: MouseEvent<HTMLAnchorElement>, url: string) => {
|
|
90
|
+
e.preventDefault();
|
|
91
|
+
|
|
92
|
+
const newUrl = new URL(url, window.location.origin);
|
|
93
|
+
const page = newUrl.searchParams.get('page');
|
|
94
|
+
|
|
95
|
+
if (page === '1') {
|
|
96
|
+
newUrl.searchParams.delete('page');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
router.push(newUrl.pathname + newUrl.search, undefined);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
createListItems();
|
|
104
|
+
}, [createListItems, page]);
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (total && total !== paginationTotal) {
|
|
108
|
+
setTotal(total);
|
|
109
|
+
}
|
|
110
|
+
}, [total, paginationTotal, setTotal]);
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (limit && limit !== paginationLimit) {
|
|
114
|
+
setLimit(limit);
|
|
115
|
+
}
|
|
116
|
+
}, [limit, paginationLimit, setLimit]);
|
|
117
|
+
|
|
118
|
+
if (render) {
|
|
119
|
+
return <>{render(pagination)}</>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<ul
|
|
124
|
+
className={twMerge(
|
|
125
|
+
'flex mt-8 mb-4 justify-center items-center',
|
|
126
|
+
containerClassName
|
|
127
|
+
)}
|
|
128
|
+
>
|
|
129
|
+
{prev && (
|
|
130
|
+
<li>
|
|
131
|
+
<Link
|
|
132
|
+
onClick={(e) => handleClick(e, prev)}
|
|
133
|
+
href={prev}
|
|
134
|
+
className={twMerge(
|
|
135
|
+
'flex cursor-pointer text-sm px-2',
|
|
136
|
+
prevClassName
|
|
137
|
+
)}
|
|
138
|
+
>
|
|
139
|
+
<span><</span>
|
|
140
|
+
<span className="hidden lg:inline-block ms-4">
|
|
141
|
+
{t('category.pagination.previous')}
|
|
142
|
+
</span>
|
|
143
|
+
</Link>
|
|
144
|
+
</li>
|
|
145
|
+
)}
|
|
146
|
+
|
|
147
|
+
{paginationItems &&
|
|
148
|
+
paginationItems?.map((item, i) => (
|
|
149
|
+
<li key={i}>
|
|
150
|
+
{item?.url != '#' ? (
|
|
151
|
+
<Link
|
|
152
|
+
onClick={(e) => handleClick(e, item.url)}
|
|
153
|
+
href={item.url}
|
|
154
|
+
className={twMerge(
|
|
155
|
+
clsx(
|
|
156
|
+
'text-xs px-2 cursor-pointer',
|
|
157
|
+
{ 'pointer-events-none': item.url === null },
|
|
158
|
+
Number(page) === Number(item?.page)
|
|
159
|
+
? 'font-semibold text-black-800'
|
|
160
|
+
: 'text-gray-400'
|
|
161
|
+
),
|
|
162
|
+
pageClassName
|
|
163
|
+
)}
|
|
164
|
+
>
|
|
165
|
+
{item?.page}
|
|
166
|
+
</Link>
|
|
167
|
+
) : (
|
|
168
|
+
<span className="cursor-default text-xs flex items-center justify-center">
|
|
169
|
+
{item?.page}
|
|
170
|
+
</span>
|
|
171
|
+
)}
|
|
172
|
+
</li>
|
|
173
|
+
))}
|
|
174
|
+
|
|
175
|
+
{showNext && (
|
|
176
|
+
<li>
|
|
177
|
+
<Link
|
|
178
|
+
onClick={(e) => handleClick(e, next)}
|
|
179
|
+
href={next}
|
|
180
|
+
className={twMerge(
|
|
181
|
+
'flex cursor-pointer text-xs px-2',
|
|
182
|
+
nextClassName
|
|
183
|
+
)}
|
|
184
|
+
>
|
|
185
|
+
<span className="hidden lg:inline-block me-4">
|
|
186
|
+
{t('category.pagination.next')}
|
|
187
|
+
</span>
|
|
188
|
+
<span>></span>
|
|
189
|
+
</Link>
|
|
190
|
+
</li>
|
|
191
|
+
)}
|
|
192
|
+
</ul>
|
|
193
|
+
);
|
|
194
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import dynamic from 'next/dynamic';
|
|
2
4
|
import plugins from 'plugins';
|
|
3
5
|
import logger from '../utils/log';
|
|
@@ -12,7 +14,8 @@ enum Plugin {
|
|
|
12
14
|
GPay = 'pz-gpay',
|
|
13
15
|
Otp = 'pz-otp',
|
|
14
16
|
BKMExpress = 'pz-bkm',
|
|
15
|
-
CreditPayment = 'pz-credit-payment'
|
|
17
|
+
CreditPayment = 'pz-credit-payment',
|
|
18
|
+
B2B = 'pz-b2b'
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
export enum Component {
|
|
@@ -24,7 +27,9 @@ export enum Component {
|
|
|
24
27
|
GPay = 'GPayOption',
|
|
25
28
|
Otp = 'Otp',
|
|
26
29
|
BKMExpress = 'BKMOption',
|
|
27
|
-
CreditPayment = 'CreditPayment'
|
|
30
|
+
CreditPayment = 'CreditPayment',
|
|
31
|
+
MyQuotationsB2B = 'AccountMyQuotations',
|
|
32
|
+
BasketB2B = 'BasketB2b'
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
const PluginComponents = new Map([
|
|
@@ -36,7 +41,8 @@ const PluginComponents = new Map([
|
|
|
36
41
|
[Plugin.GPay, [Component.GPay]],
|
|
37
42
|
[Plugin.Otp, [Component.Otp]],
|
|
38
43
|
[Plugin.BKMExpress, [Component.BKMExpress]],
|
|
39
|
-
[Plugin.CreditPayment, [Component.CreditPayment]]
|
|
44
|
+
[Plugin.CreditPayment, [Component.CreditPayment]],
|
|
45
|
+
[Plugin.B2B, [Component.MyQuotationsB2B, Component.BasketB2B]],
|
|
40
46
|
]);
|
|
41
47
|
|
|
42
48
|
const getPlugin = (component: Component) => {
|
|
@@ -81,6 +87,8 @@ export default function PluginModule({
|
|
|
81
87
|
promise = import(`${'@akinon/pz-bkm'}`);
|
|
82
88
|
} else if (plugin === Plugin.CreditPayment) {
|
|
83
89
|
promise = import(`${'@akinon/pz-credit-payment'}`);
|
|
90
|
+
} else if (plugin === Plugin.B2B) {
|
|
91
|
+
promise = import(`${'@akinon/pz-b2b'}`);
|
|
84
92
|
}
|
|
85
93
|
} catch (error) {
|
|
86
94
|
logger.error(error);
|
package/data/client/account.ts
CHANGED
|
@@ -20,6 +20,7 @@ interface GetOrdersParams {
|
|
|
20
20
|
limit?: number;
|
|
21
21
|
page?: number;
|
|
22
22
|
createdDate?: string;
|
|
23
|
+
endDate?: string;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export interface GetQuotationsResponse {
|
|
@@ -105,8 +106,10 @@ const accountApi = api.injectEndpoints({
|
|
|
105
106
|
query: (id) => buildClientRequestUrl(account.orderId(id))
|
|
106
107
|
}),
|
|
107
108
|
getOrders: builder.query<GetOrdersResponse, GetOrdersParams>({
|
|
108
|
-
query: ({ page, limit, createdDate } = {}) =>
|
|
109
|
-
buildClientRequestUrl(
|
|
109
|
+
query: ({ page, limit, createdDate, endDate } = {}) =>
|
|
110
|
+
buildClientRequestUrl(
|
|
111
|
+
account.getOrders({ page, limit, createdDate, endDate })
|
|
112
|
+
)
|
|
110
113
|
}),
|
|
111
114
|
getQuotations: builder.query<GetQuotationsResponse, void>({
|
|
112
115
|
query: () => buildClientRequestUrl(account.getQuotations)
|
package/data/client/checkout.ts
CHANGED
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
setPaymentStepBusy,
|
|
5
5
|
setSelectedBankAccountPk,
|
|
6
6
|
setSelectedCreditPaymentPk,
|
|
7
|
-
setShippingStepBusy
|
|
7
|
+
setShippingStepBusy,
|
|
8
|
+
setCardType
|
|
8
9
|
} from '../../redux/reducers/checkout';
|
|
9
10
|
import {
|
|
10
11
|
CheckoutContext,
|
|
@@ -231,6 +232,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
231
232
|
dispatch(setInstallmentOptions([]));
|
|
232
233
|
dispatch(setBankAccounts([]));
|
|
233
234
|
dispatch(setSelectedBankAccountPk(null));
|
|
235
|
+
dispatch(setCardType(null));
|
|
234
236
|
await queryFulfilled;
|
|
235
237
|
dispatch(setPaymentStepBusy(false));
|
|
236
238
|
}
|
|
@@ -256,6 +258,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
256
258
|
},
|
|
257
259
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
258
260
|
dispatch(setPaymentStepBusy(true));
|
|
261
|
+
dispatch(setCardType(arg));
|
|
259
262
|
await queryFulfilled;
|
|
260
263
|
dispatch(setPaymentStepBusy(false));
|
|
261
264
|
}
|
package/data/urls.ts
CHANGED
|
@@ -16,15 +16,17 @@ export const account = {
|
|
|
16
16
|
getOrders: ({
|
|
17
17
|
page,
|
|
18
18
|
limit,
|
|
19
|
-
createdDate
|
|
19
|
+
createdDate,
|
|
20
|
+
endDate
|
|
20
21
|
}: {
|
|
21
22
|
page?: number;
|
|
22
23
|
limit?: number;
|
|
23
24
|
createdDate?: string;
|
|
25
|
+
endDate?: string;
|
|
24
26
|
}) =>
|
|
25
27
|
`/users/orders/?page=${page || 1}&limit=${limit || 12} ${
|
|
26
28
|
createdDate ? `&created_date__gte=${createdDate}` : ''
|
|
27
|
-
}`,
|
|
29
|
+
} ${endDate ? `&created_date__lte=${endDate}` : ''}`,
|
|
28
30
|
getQuotations: '/b2b/my-quotations',
|
|
29
31
|
sendContact: '/users/contact-us',
|
|
30
32
|
passwordReset: (slug: string) => `/users/reset/${slug}`,
|
package/hooks/index.ts
CHANGED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useMemo, useReducer } from 'react';
|
|
4
|
+
import { usePathname, useSearchParams } from 'next/navigation';
|
|
5
|
+
|
|
6
|
+
export type UsePaginationType = ReturnType<typeof usePagination>;
|
|
7
|
+
|
|
8
|
+
type InitialState = {
|
|
9
|
+
page: number;
|
|
10
|
+
last: number;
|
|
11
|
+
limit: number;
|
|
12
|
+
total: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type ACTIONTYPE =
|
|
16
|
+
| { type: 'setPage'; payload: number }
|
|
17
|
+
| { type: 'setTotal'; payload: number }
|
|
18
|
+
| { type: 'setLimit'; payload: number };
|
|
19
|
+
|
|
20
|
+
function reducer(state: InitialState, action: ACTIONTYPE) {
|
|
21
|
+
switch (action.type) {
|
|
22
|
+
case 'setTotal':
|
|
23
|
+
return {
|
|
24
|
+
...state,
|
|
25
|
+
total: action.payload,
|
|
26
|
+
last: Math.ceil(action.payload / state.limit)
|
|
27
|
+
};
|
|
28
|
+
case 'setPage':
|
|
29
|
+
return { ...state, page: action.payload };
|
|
30
|
+
case 'setLimit':
|
|
31
|
+
return { ...state, limit: action.payload };
|
|
32
|
+
default:
|
|
33
|
+
throw new Error();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function usePagination(
|
|
38
|
+
_total = 0,
|
|
39
|
+
_limit = 12,
|
|
40
|
+
_page: number | undefined,
|
|
41
|
+
_last: number | undefined
|
|
42
|
+
) {
|
|
43
|
+
const pathname = usePathname();
|
|
44
|
+
const searchParams = useSearchParams();
|
|
45
|
+
const urlSearchParams = useMemo(
|
|
46
|
+
() => new URLSearchParams(searchParams.toString()),
|
|
47
|
+
[searchParams]
|
|
48
|
+
);
|
|
49
|
+
const { page, limit } = useMemo(
|
|
50
|
+
() => ({
|
|
51
|
+
page: _page || Number(searchParams.get('page')) || 1,
|
|
52
|
+
limit: _limit || Number(searchParams.get('limit'))
|
|
53
|
+
}),
|
|
54
|
+
[searchParams, _page, _limit]
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const initialState: InitialState = {
|
|
58
|
+
page,
|
|
59
|
+
limit,
|
|
60
|
+
last: _last || Math.ceil(_total / limit) || 1,
|
|
61
|
+
total: _total
|
|
62
|
+
};
|
|
63
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
dispatch({ type: 'setPage', payload: page });
|
|
67
|
+
}, [page]);
|
|
68
|
+
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
dispatch({ type: 'setLimit', payload: limit });
|
|
71
|
+
}, [limit]);
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
window.scrollTo(0, 0);
|
|
75
|
+
}, [state.page, state.limit]);
|
|
76
|
+
|
|
77
|
+
const setTotal = useCallback(
|
|
78
|
+
(total: number) => {
|
|
79
|
+
dispatch({ type: 'setTotal', payload: total });
|
|
80
|
+
},
|
|
81
|
+
[dispatch]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const setPage = useCallback(
|
|
85
|
+
(page: number) => {
|
|
86
|
+
if (page > 0 && page <= state.total) {
|
|
87
|
+
dispatch({ type: 'setPage', payload: page });
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
[dispatch, state.total]
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const setLimit = useCallback(
|
|
94
|
+
(limit: number) => {
|
|
95
|
+
dispatch({ type: 'setLimit', payload: limit });
|
|
96
|
+
},
|
|
97
|
+
[dispatch]
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const pageList = useMemo(() => {
|
|
101
|
+
return Array.from({ length: state.last }, (_, i) => {
|
|
102
|
+
urlSearchParams.set('page', (i + 1).toString());
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
page: i + 1,
|
|
106
|
+
url: `${pathname}?${urlSearchParams.toString()}`
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}, [state.last, pathname, urlSearchParams]);
|
|
110
|
+
|
|
111
|
+
const prev = useMemo(() => {
|
|
112
|
+
if (state.page > 1) {
|
|
113
|
+
urlSearchParams.set('page', (Number(state.page) - 1).toString());
|
|
114
|
+
return `${pathname}?${urlSearchParams.toString()}`;
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}, [state.page, pathname, urlSearchParams]);
|
|
118
|
+
|
|
119
|
+
const next = useMemo(() => {
|
|
120
|
+
if (Number(state.page) < Number(state.last)) {
|
|
121
|
+
urlSearchParams.set('page', (Number(state.page) + 1).toString());
|
|
122
|
+
return `${pathname}?${urlSearchParams.toString()}`;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}, [state.page, state.last, pathname, urlSearchParams]);
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
...state,
|
|
129
|
+
setTotal,
|
|
130
|
+
setPage,
|
|
131
|
+
setLimit,
|
|
132
|
+
pageList,
|
|
133
|
+
prev,
|
|
134
|
+
next
|
|
135
|
+
};
|
|
136
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.18.0",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@typescript-eslint/eslint-plugin": "6.7.4",
|
|
32
32
|
"@typescript-eslint/parser": "6.7.4",
|
|
33
33
|
"eslint": "^8.14.0",
|
|
34
|
-
"@akinon/eslint-plugin-projectzero": "1.
|
|
34
|
+
"@akinon/eslint-plugin-projectzero": "1.18.0",
|
|
35
35
|
"eslint-config-prettier": "8.5.0"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/plugins.js
CHANGED
|
@@ -10,14 +10,14 @@ export interface Product {
|
|
|
10
10
|
};
|
|
11
11
|
attributes_kwargs: any;
|
|
12
12
|
base_code: string;
|
|
13
|
-
basket_offers: {
|
|
13
|
+
basket_offers: Array<{
|
|
14
14
|
kwargs: { show_benefit_products: boolean };
|
|
15
15
|
label: string;
|
|
16
16
|
listing_kwargs: {
|
|
17
17
|
[key: string]: any;
|
|
18
18
|
};
|
|
19
19
|
pk: number;
|
|
20
|
-
}
|
|
20
|
+
}>;
|
|
21
21
|
currency_type: string;
|
|
22
22
|
data_source: null;
|
|
23
23
|
extra_attributes: {
|
package/utils/get-currency.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
3
|
import getSymbolFromCurrency from 'currency-symbol-map';
|
|
4
|
+
import { getCurrencyLabel } from './get-currency-label';
|
|
4
5
|
|
|
5
6
|
type GetCurrencyType = {
|
|
6
7
|
currencyCode: string;
|
|
@@ -17,10 +18,11 @@ export const getCurrency = (args: GetCurrencyType) => {
|
|
|
17
18
|
useCurrencySpace = true
|
|
18
19
|
} = args;
|
|
19
20
|
|
|
21
|
+
const currencyLabel = getCurrencyLabel(currencyCode);
|
|
20
22
|
const currencySpace = useCurrencySpace ? ' ' : '';
|
|
21
23
|
const currency = useCurrencySymbol
|
|
22
|
-
? `${getSymbolFromCurrency(
|
|
23
|
-
:
|
|
24
|
+
? `${getSymbolFromCurrency(currencyLabel)}`
|
|
25
|
+
: currencyLabel;
|
|
24
26
|
const currencyAfterPrice = useCurrencyAfterPrice
|
|
25
27
|
? `${currencySpace}${currency}`
|
|
26
28
|
: `${currency}${currencySpace}`;
|
package/utils/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { CDNOptions, ClientRequestOptions } from '../types';
|
|
|
5
5
|
export * from './get-currency';
|
|
6
6
|
export * from './menu-generator';
|
|
7
7
|
export * from './generate-commerce-search-params';
|
|
8
|
+
export * from './get-currency-label';
|
|
8
9
|
|
|
9
10
|
export function getCookie(name: string) {
|
|
10
11
|
if (typeof document === 'undefined') {
|