@akinon/projectzero 1.74.0 → 1.75.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @akinon/projectzero
2
2
 
3
+ ## 1.75.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1ebe1da: ZERO-3016:move pagination fixes and add optional chaining
8
+
3
9
  ## 1.74.0
4
10
 
5
11
  ## 1.73.0
@@ -1,5 +1,42 @@
1
1
  # projectzeronext
2
2
 
3
+ ## 1.75.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f268c94: ZERO-3107: Upgrade version for tailwindcss
8
+ - 1ebe1da: ZERO-3016:move pagination fixes and add optional chaining
9
+ - 7d2d66e: ZERO-3012: Upgrade version for tailwindcss
10
+ - 3344bca: ZERO-3013: Enable web vitals tracking in settings.js
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [81248a1]
15
+ - Updated dependencies [cc538c6]
16
+ - Updated dependencies [663bda9]
17
+ - Updated dependencies [94eb825]
18
+ - Updated dependencies [0ab91e5]
19
+ - Updated dependencies [3010514]
20
+ - Updated dependencies [37547c0]
21
+ - Updated dependencies [5a333a5]
22
+ - Updated dependencies [ca774b3]
23
+ - Updated dependencies [3344bca]
24
+ - @akinon/next@1.75.0
25
+ - @akinon/pz-akifast@1.75.0
26
+ - @akinon/pz-b2b@1.75.0
27
+ - @akinon/pz-basket-gift-pack@1.75.0
28
+ - @akinon/pz-bkm@1.75.0
29
+ - @akinon/pz-checkout-gift-pack@1.75.0
30
+ - @akinon/pz-click-collect@1.75.0
31
+ - @akinon/pz-credit-payment@1.75.0
32
+ - @akinon/pz-gpay@1.75.0
33
+ - @akinon/pz-masterpass@1.75.0
34
+ - @akinon/pz-one-click-checkout@1.75.0
35
+ - @akinon/pz-otp@1.75.0
36
+ - @akinon/pz-pay-on-delivery@1.75.0
37
+ - @akinon/pz-saved-card@1.75.0
38
+ - @akinon/pz-tabby-extension@1.75.0
39
+
3
40
  ## 1.74.0
4
41
 
5
42
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "projectzeronext",
3
- "version": "1.74.0",
3
+ "version": "1.75.0",
4
4
  "private": true,
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -22,21 +22,21 @@
22
22
  "prestart": "pz-prestart"
23
23
  },
24
24
  "dependencies": {
25
- "@akinon/next": "1.74.0",
26
- "@akinon/pz-akifast": "1.74.0",
27
- "@akinon/pz-b2b": "1.74.0",
28
- "@akinon/pz-basket-gift-pack": "1.74.0",
29
- "@akinon/pz-bkm": "1.74.0",
30
- "@akinon/pz-checkout-gift-pack": "1.74.0",
31
- "@akinon/pz-click-collect": "1.74.0",
32
- "@akinon/pz-credit-payment": "1.74.0",
33
- "@akinon/pz-gpay": "1.74.0",
34
- "@akinon/pz-masterpass": "1.74.0",
35
- "@akinon/pz-one-click-checkout": "1.74.0",
36
- "@akinon/pz-otp": "1.74.0",
37
- "@akinon/pz-pay-on-delivery": "1.74.0",
38
- "@akinon/pz-saved-card": "1.74.0",
39
- "@akinon/pz-tabby-extension": "1.74.0",
25
+ "@akinon/next": "1.75.0",
26
+ "@akinon/pz-akifast": "1.75.0",
27
+ "@akinon/pz-b2b": "1.75.0",
28
+ "@akinon/pz-basket-gift-pack": "1.75.0",
29
+ "@akinon/pz-bkm": "1.75.0",
30
+ "@akinon/pz-checkout-gift-pack": "1.75.0",
31
+ "@akinon/pz-click-collect": "1.75.0",
32
+ "@akinon/pz-credit-payment": "1.75.0",
33
+ "@akinon/pz-gpay": "1.75.0",
34
+ "@akinon/pz-masterpass": "1.75.0",
35
+ "@akinon/pz-one-click-checkout": "1.75.0",
36
+ "@akinon/pz-otp": "1.75.0",
37
+ "@akinon/pz-pay-on-delivery": "1.75.0",
38
+ "@akinon/pz-saved-card": "1.75.0",
39
+ "@akinon/pz-tabby-extension": "1.75.0",
40
40
  "@hookform/resolvers": "2.9.0",
41
41
  "@next/third-parties": "14.1.0",
42
42
  "@react-google-maps/api": "2.17.1",
@@ -47,7 +47,7 @@
47
47
  "next-auth": "4.24.5",
48
48
  "next-pwa": "5.6.0",
49
49
  "pino": "8.11.0",
50
- "postcss": "8.4.31",
50
+ "postcss": "8.4.49",
51
51
  "react": "18.2.0",
52
52
  "react-dom": "18.2.0",
53
53
  "react-google-recaptcha": "2.1.0",
@@ -57,10 +57,11 @@
57
57
  "react-string-replace": "1.1.0",
58
58
  "start-server-and-test": "2.0.3",
59
59
  "tailwind-merge": "1.8.0",
60
+ "tailwindcss": "3.4.17",
60
61
  "yup": "0.32.11"
61
62
  },
62
63
  "devDependencies": {
63
- "@akinon/eslint-plugin-projectzero": "1.74.0",
64
+ "@akinon/eslint-plugin-projectzero": "1.75.0",
64
65
  "@semantic-release/changelog": "6.0.2",
65
66
  "@semantic-release/exec": "6.0.3",
66
67
  "@semantic-release/git": "10.0.1",
@@ -75,7 +76,7 @@
75
76
  "@types/react-dom": "18.2.12",
76
77
  "@typescript-eslint/eslint-plugin": "6.7.4",
77
78
  "@typescript-eslint/parser": "6.7.4",
78
- "autoprefixer": "10.4.13",
79
+ "autoprefixer": "10.4.20",
79
80
  "client-only": "0.0.1",
80
81
  "clsx": "1.1.1",
81
82
  "currency-symbol-map": "5.1.0",
@@ -96,7 +97,7 @@
96
97
  "stylelint-config-standard": "25.0.0",
97
98
  "stylelint-scss": "4.2.0",
98
99
  "stylelint-selector-bem-pattern": "2.1.1",
99
- "tailwindcss": "3.4.12",
100
+ "tailwindcss": "3.4.14",
100
101
  "ts-jest": "29.1.1",
101
102
  "ts-node": "10.7.0",
102
103
  "typescript": "5.2.2"
@@ -1,8 +1,8 @@
1
- import { useCallback, useEffect, useState } from 'react';
1
+ import { MouseEvent, 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 { Button } from '@theme/components';
5
+ import { Link, Button, LoaderSpinner } 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';
@@ -25,7 +25,8 @@ export const Pagination = (props: PaginationProps) => {
25
25
  type = 'list',
26
26
  onPageChange,
27
27
  direction,
28
- render
28
+ render,
29
+ isLoading
29
30
  } = props;
30
31
 
31
32
  const pagination = usePagination(total, limit, currentPage, numberOfPages);
@@ -92,7 +93,9 @@ export const Pagination = (props: PaginationProps) => {
92
93
  }
93
94
  }, [numberOfPages, page, pageList, threshold]);
94
95
 
95
- const handleClick = (url: string) => {
96
+ const handleClick = (e: MouseEvent<HTMLAnchorElement>, url: string) => {
97
+ e.preventDefault();
98
+
96
99
  const newUrl = new URL(url, window.location.origin);
97
100
  const page = newUrl.searchParams.get('page');
98
101
 
@@ -117,6 +120,13 @@ export const Pagination = (props: PaginationProps) => {
117
120
  onPageChange(changingPage);
118
121
  };
119
122
 
123
+ useEffect(() => {
124
+ if (type === 'infinite' && page === 1) {
125
+ setPrevPage(1);
126
+ setNextPage(1);
127
+ }
128
+ }, [page]);
129
+
120
130
  useEffect(() => {
121
131
  if (inView) {
122
132
  handlePageChange();
@@ -127,7 +137,7 @@ export const Pagination = (props: PaginationProps) => {
127
137
  if (type === 'list') {
128
138
  createListItems();
129
139
  }
130
- }, [createListItems, type]);
140
+ }, [page]); // eslint-disable-line react-hooks/exhaustive-deps
131
141
 
132
142
  useEffect(() => {
133
143
  if (total && total !== paginationTotal) {
@@ -147,21 +157,23 @@ export const Pagination = (props: PaginationProps) => {
147
157
 
148
158
  return direction === 'prev' && type !== 'list' ? (
149
159
  <>
150
- {Number(prevPage) !== 1 && (
151
- <div className="flex justify-center items-center">
152
- <Button
153
- className={twMerge('px-5', moreButtonClassName)}
154
- onClick={() => handlePageChange()}
155
- >
156
- {t('category.pagination.load_previous_page')}
157
- </Button>
158
- </div>
159
- )}
160
+ <div className="flex items-center justify-center">
161
+ <Button
162
+ className={twMerge('px-5', moreButtonClassName)}
163
+ onClick={() => handlePageChange()}
164
+ >
165
+ {isLoading ? (
166
+ <LoaderSpinner className="h-4 w-4" />
167
+ ) : (
168
+ t('category.pagination.load_previous_page')
169
+ )}
170
+ </Button>
171
+ </div>
160
172
  </>
161
173
  ) : (
162
174
  <>
163
175
  {type === 'more' && (
164
- <div className="flex justify-center items-center">
176
+ <div className="flex items-center justify-center">
165
177
  <Button
166
178
  className={twMerge(
167
179
  'px-5',
@@ -173,7 +185,11 @@ export const Pagination = (props: PaginationProps) => {
173
185
  onClick={() => handlePageChange()}
174
186
  disabled={Number(nextPage) === Number(last)}
175
187
  >
176
- {t('category.pagination.more')}
188
+ {isLoading ? (
189
+ <LoaderSpinner className="h-4 w-4" />
190
+ ) : (
191
+ t('category.pagination.more')
192
+ )}
177
193
  </Button>
178
194
  </div>
179
195
  )}
@@ -183,8 +199,9 @@ export const Pagination = (props: PaginationProps) => {
183
199
  )}
184
200
 
185
201
  {(type === 'infinite' || type === 'more') &&
186
- Number(nextPage) === last && (
187
- <p className="text-center mt-8">
202
+ Number(nextPage) === last &&
203
+ !isLoading && (
204
+ <p className="mt-8 text-center">
188
205
  {t('category.pagination.shown_items')}
189
206
  </p>
190
207
  )}
@@ -192,35 +209,37 @@ export const Pagination = (props: PaginationProps) => {
192
209
  {type === 'list' && (
193
210
  <ul
194
211
  className={twMerge(
195
- 'flex mt-8 mb-4 justify-center items-center',
212
+ 'mb-4 mt-8 flex items-center justify-center',
196
213
  containerClassName
197
214
  )}
198
215
  >
199
216
  {prev && currentPage !== 1 && (
200
217
  <li>
201
- <button
202
- onClick={() => handleClick(prev)}
218
+ <Link
219
+ onClick={(e) => handleClick(e, prev)}
220
+ href={prev}
203
221
  className={twMerge(
204
- 'flex cursor-pointer text-sm px-2',
222
+ 'flex cursor-pointer px-2 text-sm items-center',
205
223
  prevClassName
206
224
  )}
207
225
  >
208
226
  <span>&lt;</span>
209
- <span className="hidden lg:inline-block ms-4">
227
+ <span className="ms-4 hidden lg:inline-block">
210
228
  {t('category.pagination.previous')}
211
229
  </span>
212
- </button>
230
+ </Link>
213
231
  </li>
214
232
  )}
215
233
 
216
234
  {paginationItems.map((item, i) => (
217
235
  <li key={i}>
218
236
  {item?.url != '#' ? (
219
- <button
220
- onClick={() => handleClick(item.url)}
237
+ <Link
238
+ onClick={(e) => handleClick(e, item.url)}
239
+ href={item.url}
221
240
  className={twMerge(
222
241
  clsx(
223
- 'text-xs px-2 cursor-pointer',
242
+ 'cursor-pointer px-2 text-xs items-center',
224
243
  { 'pointer-events-none': item.url === null },
225
244
  Number(page) === Number(item?.page)
226
245
  ? 'font-semibold text-black-800'
@@ -230,9 +249,9 @@ export const Pagination = (props: PaginationProps) => {
230
249
  )}
231
250
  >
232
251
  {item?.page}
233
- </button>
252
+ </Link>
234
253
  ) : (
235
- <span className="cursor-default text-xs flex items-center justify-center">
254
+ <span className="flex cursor-default items-center justify-center text-xs">
236
255
  {item?.page}
237
256
  </span>
238
257
  )}
@@ -241,18 +260,19 @@ export const Pagination = (props: PaginationProps) => {
241
260
 
242
261
  {showNext && (
243
262
  <li>
244
- <button
245
- onClick={() => handleClick(next)}
263
+ <Link
264
+ onClick={(e) => handleClick(e, next)}
265
+ href={next}
246
266
  className={twMerge(
247
- 'flex cursor-pointer text-xs px-2',
267
+ 'flex cursor-pointer px-2 text-xs items-center',
248
268
  nextClassName
249
269
  )}
250
270
  >
251
- <span className="hidden lg:inline-block me-4">
271
+ <span className="me-4 hidden lg:inline-block">
252
272
  {t('category.pagination.next')}
253
273
  </span>
254
274
  <span>&gt;</span>
255
- </button>
275
+ </Link>
256
276
  </li>
257
277
  )}
258
278
  </ul>
@@ -23,6 +23,7 @@ export interface PaginationProps {
23
23
  type?: 'infinite' | 'list' | 'more';
24
24
  onPageChange?: (page: number) => void;
25
25
  direction?: 'next' | 'prev';
26
+ isLoading?: boolean;
26
27
  }
27
28
 
28
29
  export type FileInputProps = React.HTMLProps<HTMLInputElement>;
@@ -5,6 +5,9 @@ const commerceUrl = encodeURI(process.env.SERVICE_BACKEND_URL ?? 'default');
5
5
 
6
6
  /** @type {import('@akinon/next/types').Settings} */
7
7
  module.exports = {
8
+ webVitals: {
9
+ enabled: true
10
+ },
8
11
  commerceUrl,
9
12
  commonProductAttributes: [
10
13
  { translationKey: 'color', key: 'color' },
@@ -70,9 +70,9 @@ const CategoryActiveFilters = () => {
70
70
  return (
71
71
  <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-2 mb-4">
72
72
  {facets.map((facet) =>
73
- facet.data.choices
74
- .filter((choice) => choice.is_selected)
75
- .map(
73
+ facet?.data?.choices
74
+ ?.filter((choice) => choice.is_selected)
75
+ ?.map(
76
76
  (choice) =>
77
77
  Number(choice.real_depth) !== 2 && (
78
78
  <div
@@ -112,7 +112,7 @@ export const FilterItem = ({ facet, isPending, startTransition }: Props) => {
112
112
  };
113
113
 
114
114
  const Component = getComponentByWidgetType(facet.widget_type, facet.key);
115
- const choices = sortChoices(facet.key, [...facet.data.choices]);
115
+ const choices = sortChoices(facet?.key, [...(facet?.data?.choices || [])]);
116
116
 
117
117
  return (
118
118
  <Accordion
@@ -24,7 +24,7 @@ export const Filters = (props: Props) => {
24
24
 
25
25
  const haveFilter = useMemo(() => {
26
26
  return facets.some((facet) =>
27
- facet.data.choices.some((choice) => choice.is_selected)
27
+ facet?.data?.choices?.some((choice) => choice.is_selected)
28
28
  );
29
29
  }, [facets]);
30
30
 
@@ -17,7 +17,7 @@ export default async function Layout({
17
17
  <>
18
18
  <div
19
19
  className={clsx(
20
- data.category?.attributes?.category_banner
20
+ data?.category?.attributes?.category_banner
21
21
  ? 'relative w-full'
22
22
  : 'container px-4 mx-auto lg:px-0 lg:my-4'
23
23
  )}
@@ -26,13 +26,13 @@ export default async function Layout({
26
26
  <div
27
27
  className={clsx(
28
28
  'my-4 lg:mt-7',
29
- data.category?.attributes?.category_banner &&
29
+ data?.category?.attributes?.category_banner &&
30
30
  'lg:absolute lg:inset-x-0 z-10 container lg:my-4 mx-auto'
31
31
  )}
32
32
  >
33
33
  <Breadcrumb breadcrumbList={breadcrumbData} />
34
34
  </div>
35
- <CategoryBanner {...data.category?.attributes?.category_banner} />
35
+ <CategoryBanner {...data?.category?.attributes?.category_banner} />
36
36
  </div>
37
37
  <ListPage data={data} />
38
38
  </>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/projectzero",
3
- "version": "1.74.0",
3
+ "version": "1.75.0",
4
4
  "private": false,
5
5
  "description": "CLI tool to manage your Project Zero Next project",
6
6
  "bin": {