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