@akinon/pz-similar-products 1.113.0-snapshot-ZERO-3878-20251204105428 → 1.114.0-rc.21

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.
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useCallback, useRef } from 'react';
1
+ import { useState, useEffect, useCallback } from 'react';
2
2
  import { Product } from '@akinon/next/types';
3
3
  import {
4
4
  useLazyGetSimilarProductsByUrlQuery,
@@ -13,7 +13,6 @@ import {
13
13
  validateImageFromDataUrl,
14
14
  type ImageValidationResult
15
15
  } from '../utils/image-validation';
16
- import { debounce } from '../utils';
17
16
 
18
17
  type SearchResults = SimilarProductsListResponse;
19
18
 
@@ -25,7 +24,6 @@ export function useSimilarProducts(product: Product) {
25
24
  const { t } = useLocalization();
26
25
  const [currentImageUrl, setCurrentImageUrl] = useState('');
27
26
  const [fileError, setFileError] = useState('');
28
- const [searchText, setSearchText] = useState('');
29
27
  const [searchResults, setSearchResults] = useState<SearchResults | null>(
30
28
  null
31
29
  );
@@ -35,16 +33,6 @@ export function useSimilarProducts(product: Product) {
35
33
  const [isCropProcessing, setIsCropProcessing] = useState(false);
36
34
  const [loadedPages, setLoadedPages] = useState<Set<number>>(new Set([1]));
37
35
  const [allLoadedProducts, setAllLoadedProducts] = useState<Product[]>([]);
38
- const [currentImageBase64, setCurrentImageBase64] = useState<string>('');
39
- const [hasCroppedImage, setHasCroppedImage] = useState(false);
40
-
41
- const searchTextRef = useRef<string>('');
42
- const hasUploadedImageRef = useRef<boolean>(false);
43
-
44
- const setSearchTextWithRef = useCallback((text: string) => {
45
- setSearchText(text);
46
- searchTextRef.current = text;
47
- }, []);
48
36
 
49
37
  const [fetchSimilarProductsByUrl, { isLoading: isUrlSearchLoading }] =
50
38
  useLazyGetSimilarProductsByUrlQuery();
@@ -438,24 +426,17 @@ export function useSimilarProducts(product: Product) {
438
426
  );
439
427
 
440
428
  const fetchSimilarProductsByImageUrl = useCallback(
441
- async (imageUrl: string, overrideText?: string) => {
429
+ async (imageUrl: string) => {
442
430
  setFileError('');
443
-
444
431
  try {
445
432
  const productPk = product?.pk;
446
433
  const excludedIds = productPk ? [productPk] : undefined;
447
434
 
448
- const textToUse =
449
- overrideText !== undefined ? overrideText : searchTextRef.current;
450
-
451
- const requestParams = {
435
+ const result = await fetchSimilarProductsByUrl({
452
436
  url: imageUrl,
453
437
  limit: 20,
454
- excluded_product_ids: excludedIds,
455
- text: textToUse || undefined
456
- };
457
-
458
- const result = await fetchSimilarProductsByUrl(requestParams).unwrap();
438
+ excluded_product_ids: excludedIds
439
+ }).unwrap();
459
440
 
460
441
  await handleSearchResults(result);
461
442
  return result;
@@ -469,8 +450,6 @@ export function useSimilarProducts(product: Product) {
469
450
  [
470
451
  fetchSimilarProductsByUrl,
471
452
  product?.pk,
472
- searchText,
473
- searchTextRef,
474
453
  handleSearchResults,
475
454
  updateResultsAndKey,
476
455
  createEmptySearchResults,
@@ -483,62 +462,31 @@ export function useSimilarProducts(product: Product) {
483
462
  if (product?.productimage_set?.length > 0) {
484
463
  const initialImageUrl = product.productimage_set[0].image;
485
464
  setCurrentImageUrl(initialImageUrl);
486
- setHasCroppedImage(false);
487
- setCurrentImageBase64('');
488
- setHasUploadedImage(false);
489
- hasUploadedImageRef.current = false;
490
465
  }
491
466
  }, [product]);
492
467
 
493
468
  const fetchSimilarProductsByBase64 = useCallback(
494
- async (
495
- base64Image: string,
496
- overrideText?: string,
497
- forceExclude?: boolean
498
- ) => {
469
+ async (base64Image: string) => {
499
470
  const base64Data = base64Image.startsWith('data:')
500
471
  ? base64Image.split(',')[1]
501
472
  : base64Image;
502
473
 
503
- const textToUse =
504
- overrideText !== undefined ? overrideText : searchTextRef.current;
505
-
506
- const shouldExclude =
507
- forceExclude !== undefined ? forceExclude : !hasUploadedImage;
508
-
509
- const requestData = {
510
- image: base64Data,
511
- limit: 20,
512
- excluded_product_ids: shouldExclude
513
- ? product?.pk
514
- ? [product.pk]
515
- : undefined
516
- : undefined,
517
- text: textToUse || undefined
518
- };
519
-
520
474
  return handleImageSearch(
521
- async () => getSimilarProductsByImage(requestData).unwrap(),
475
+ async () =>
476
+ getSimilarProductsByImage({
477
+ image: base64Data,
478
+ limit: 20
479
+ }).unwrap(),
522
480
  base64Image,
523
481
  'Image search'
524
482
  );
525
483
  },
526
- [
527
- getSimilarProductsByImage,
528
- searchText,
529
- searchTextRef,
530
- handleImageSearch,
531
- hasUploadedImage,
532
- product?.pk
533
- ]
484
+ [getSimilarProductsByImage, handleImageSearch]
534
485
  );
535
486
 
536
487
  const fetchSimilarProductsByImageCrop = useCallback(
537
- async (dataString: string, excludeCurrentProduct: boolean = true) => {
488
+ async (dataString: string) => {
538
489
  setFileError('');
539
-
540
- setCurrentImageBase64(dataString);
541
- setHasCroppedImage(true);
542
490
  if (dataString.startsWith('data:application/x-cors-fallback;base64,')) {
543
491
  try {
544
492
  const fallbackDataEncoded = dataString.replace(
@@ -601,12 +549,9 @@ export function useSimilarProducts(product: Product) {
601
549
  getSimilarProductsByImage({
602
550
  image: base64Data,
603
551
  limit: 20,
604
- excluded_product_ids: excludeCurrentProduct
605
- ? product?.pk
606
- ? [product.pk]
607
- : undefined
608
- : undefined,
609
- text: searchTextRef.current || undefined
552
+ excluded_product_ids: product?.pk
553
+ ? [product.pk]
554
+ : undefined
610
555
  }).unwrap(),
611
556
  croppedBase64,
612
557
  'Proxy crop search'
@@ -656,12 +601,7 @@ export function useSimilarProducts(product: Product) {
656
601
  getSimilarProductsByImage({
657
602
  image: base64Data,
658
603
  limit: 20,
659
- excluded_product_ids: excludeCurrentProduct
660
- ? product?.pk
661
- ? [product.pk]
662
- : undefined
663
- : undefined,
664
- text: searchTextRef.current || undefined
604
+ excluded_product_ids: product?.pk ? [product.pk] : undefined
665
605
  }).unwrap(),
666
606
  dataString,
667
607
  'Image crop search'
@@ -669,14 +609,11 @@ export function useSimilarProducts(product: Product) {
669
609
  },
670
610
  [
671
611
  getSimilarProductsByImage,
672
- searchText,
673
- searchTextRef,
674
612
  handleImageSearch,
675
613
  product,
676
614
  fetchSimilarProductsByImageUrl,
677
615
  setFileError,
678
- t,
679
- hasUploadedImage
616
+ t
680
617
  ]
681
618
  );
682
619
 
@@ -687,8 +624,6 @@ export function useSimilarProducts(product: Product) {
687
624
  const file = event.target.files?.[0];
688
625
  if (!file) return;
689
626
 
690
- setSearchTextWithRef('');
691
-
692
627
  try {
693
628
  let processedFile = file;
694
629
 
@@ -715,9 +650,6 @@ export function useSimilarProducts(product: Product) {
715
650
  const dataUrl = e.target?.result as string;
716
651
  setCurrentImageUrl(dataUrl);
717
652
  setHasUploadedImage(true);
718
- hasUploadedImageRef.current = true;
719
- setHasCroppedImage(false);
720
- setCurrentImageBase64('');
721
653
 
722
654
  const metadataValidation = await validateImageFromDataUrl(dataUrl);
723
655
  if (!metadataValidation.isValid) {
@@ -726,7 +658,7 @@ export function useSimilarProducts(product: Product) {
726
658
  );
727
659
  return;
728
660
  }
729
- fetchSimilarProductsByBase64(dataUrl, undefined, false);
661
+ fetchSimilarProductsByBase64(dataUrl);
730
662
  };
731
663
 
732
664
  reader.onerror = () =>
@@ -747,8 +679,6 @@ export function useSimilarProducts(product: Product) {
747
679
 
748
680
  try {
749
681
  setCurrentImageUrl(base64Image);
750
- setCurrentImageBase64(base64Image);
751
- setHasCroppedImage(true);
752
682
 
753
683
  const metadataValidation = await validateImageFromDataUrl(base64Image);
754
684
  if (!metadataValidation.isValid) {
@@ -758,14 +688,10 @@ export function useSimilarProducts(product: Product) {
758
688
  return;
759
689
  }
760
690
 
761
- if (hasUploadedImageRef.current) {
762
- await fetchSimilarProductsByBase64(
763
- base64Image,
764
- searchTextRef.current,
765
- false
766
- );
691
+ if (hasUploadedImage) {
692
+ await fetchSimilarProductsByBase64(base64Image);
767
693
  } else {
768
- await fetchSimilarProductsByImageCrop(base64Image, true);
694
+ await fetchSimilarProductsByImageCrop(base64Image);
769
695
  }
770
696
  } catch (error) {
771
697
  setFileError(t('common.similar_products.errors.crop_processing_error'));
@@ -956,11 +882,6 @@ export function useSimilarProducts(product: Product) {
956
882
  setLoadedPages(new Set([1]));
957
883
  }, []);
958
884
 
959
- const resetCropState = useCallback(() => {
960
- setHasCroppedImage(false);
961
- setCurrentImageBase64('');
962
- }, []);
963
-
964
885
  const clearFileInput = useCallback(
965
886
  (fileInputRef: React.RefObject<HTMLInputElement>) => {
966
887
  if (fileInputRef.current) {
@@ -970,47 +891,6 @@ export function useSimilarProducts(product: Product) {
970
891
  []
971
892
  );
972
893
 
973
- const handleTextSearch = useCallback(async () => {
974
- const textToUse = searchTextRef.current || searchText;
975
-
976
- if (hasCroppedImage && currentImageBase64) {
977
- await fetchSimilarProductsByBase64(currentImageBase64, textToUse, !hasUploadedImage);
978
- } else if (hasUploadedImage && currentImageUrl) {
979
- await fetchSimilarProductsByBase64(currentImageUrl, textToUse, false);
980
- } else if (currentImageUrl) {
981
- await fetchSimilarProductsByImageUrl(currentImageUrl, textToUse);
982
- }
983
- }, [
984
- searchText,
985
- searchTextRef,
986
- currentImageUrl,
987
- currentImageBase64,
988
- hasCroppedImage,
989
- hasUploadedImage,
990
- fetchSimilarProductsByImageUrl,
991
- fetchSimilarProductsByBase64
992
- ]);
993
-
994
- const handleClearText = useCallback(async () => {
995
- setSearchTextWithRef('');
996
-
997
- if (hasCroppedImage && currentImageBase64) {
998
- await fetchSimilarProductsByBase64(currentImageBase64, '', !hasUploadedImage);
999
- } else if (hasUploadedImage && currentImageUrl) {
1000
- await fetchSimilarProductsByBase64(currentImageUrl, '', false);
1001
- } else if (currentImageUrl) {
1002
- await fetchSimilarProductsByImageUrl(currentImageUrl, '');
1003
- }
1004
- }, [
1005
- hasCroppedImage,
1006
- currentImageBase64,
1007
- currentImageUrl,
1008
- hasUploadedImage,
1009
- fetchSimilarProductsByBase64,
1010
- fetchSimilarProductsByImageUrl,
1011
- setSearchTextWithRef
1012
- ]);
1013
-
1014
894
  const handleLoadMore = async () => {
1015
895
  if (!searchResults?.pagination || isLoading) return;
1016
896
 
@@ -1051,8 +931,6 @@ export function useSimilarProducts(product: Product) {
1051
931
  setCurrentImageUrl,
1052
932
  isLoading,
1053
933
  fileError,
1054
- searchText,
1055
- setSearchText: setSearchTextWithRef,
1056
934
  searchResults,
1057
935
  resultsKey,
1058
936
  hasUploadedImage,
@@ -1071,9 +949,6 @@ export function useSimilarProducts(product: Product) {
1071
949
  allLoadedProducts,
1072
950
  clearError,
1073
951
  clearResults,
1074
- clearFileInput,
1075
- handleTextSearch,
1076
- handleClearText,
1077
- resetCropState
952
+ clearFileInput
1078
953
  };
1079
954
  }
@@ -58,10 +58,6 @@ export interface SimilarProductsModalProps {
58
58
  showResetButton?: boolean;
59
59
  settings?: any;
60
60
  className?: string;
61
- searchText?: string;
62
- setSearchText?: (text: string) => void;
63
- handleTextSearch?: () => void;
64
- handleClearText?: () => void;
65
61
  }
66
62
 
67
63
  export interface FilterSidebarProps {
@@ -71,8 +67,6 @@ export interface FilterSidebarProps {
71
67
  isLoading: boolean;
72
68
  handleFacetChange: (facetKey: string, choiceValue: string | number) => void;
73
69
  removeFacetFilter: (facetKey: string, choiceValue: string | number) => void;
74
- searchText?: string;
75
- setSearchText?: (text: string) => void;
76
70
  currentImageUrl: string;
77
71
  isCropping: boolean;
78
72
  imageRef: React.RefObject<HTMLImageElement>;
@@ -132,8 +126,6 @@ export interface CustomRendererProps {
132
126
  onSortChange: (value: string) => void;
133
127
  onFilterMenuToggle: () => void;
134
128
  isLoading: boolean;
135
- searchText?: string;
136
- setSearchText?: (text: string) => void;
137
129
  }) => React.ReactNode;
138
130
  renderSortDropdown?: (props: {
139
131
  sorters: SortOption[];
@@ -149,17 +141,6 @@ export interface CustomRendererProps {
149
141
  onClick: () => void;
150
142
  isLoading: boolean;
151
143
  }) => React.ReactNode;
152
- renderModalSearchInput?: (props: {
153
- searchText: string;
154
- setSearchText: (text: string) => void;
155
- isLoading: boolean;
156
- placeholder: string;
157
- onSearch?: () => void;
158
- }) => React.ReactNode;
159
- renderSearchIcon?: (props: {
160
- disabled: boolean;
161
- onClick?: () => void;
162
- }) => React.ReactNode;
163
144
  renderEmptyState?: () => React.ReactNode;
164
145
  };
165
146
  filterSidebar?: {
@@ -238,12 +219,6 @@ export interface CustomRendererProps {
238
219
  onClearAll: () => void;
239
220
  isLoading: boolean;
240
221
  }) => React.ReactNode;
241
- renderTextSearch?: (props: {
242
- searchText: string;
243
- setSearchText: (text: string) => void;
244
- isLoading: boolean;
245
- placeholder: string;
246
- }) => React.ReactNode;
247
222
  };
248
223
  resultsGrid?: {
249
224
  renderGrid?: (props: ResultsGridProps) => React.ReactNode;
@@ -334,7 +309,6 @@ export interface SimilarProductsSettings {
334
309
  resultsPerPage?: number;
335
310
  enableCropping?: boolean;
336
311
  enableFileUpload?: boolean;
337
- enableTextSearch?: boolean;
338
312
  paginationType?: 'pagination' | 'load-more' | 'infinite-scroll';
339
313
  loadMoreText?: string;
340
314
  loadMoreStyle?: 'button' | 'auto';
@@ -355,22 +329,10 @@ export interface SimilarProductsSettings {
355
329
  controlsContainer?: string;
356
330
  controlsInner?: string;
357
331
  controlsLeft?: string;
358
- controlsCenter?: string;
359
332
  controlsRight?: string;
360
333
  itemCount?: string;
361
334
  sortDropdown?: string;
362
335
  filterToggleButton?: string;
363
- modalSearchInput?: string;
364
- modalSearchContainer?: string;
365
- modalSearchButton?: string;
366
- modalSearchIcon?: string;
367
- modalSearchClearButton?: string;
368
- modalSearchClearIcon?: string;
369
- searchButtonIcon?: string;
370
- modalCloseIcon?: string;
371
- filterIcon?: string;
372
- filterRemoveIcon?: string;
373
- imageSearchButtonIcon?: string;
374
336
 
375
337
  filterSidebarMobileHeader?: string;
376
338
  filterSidebarMobileTitle?: string;
@@ -452,19 +414,6 @@ export interface SimilarProductsSettings {
452
414
  mobileActiveFilterTag?: string;
453
415
  mobileClearAllButton?: string;
454
416
  filterSidebarMobileOverlay?: string;
455
-
456
- textSearchContainer?: string;
457
- textSearchLabel?: string;
458
- textSearchInput?: string;
459
- };
460
- iconNames?: {
461
- searchButton?: string;
462
- modalClose?: string;
463
- filter?: string;
464
- filterRemove?: string;
465
- modalSearch?: string;
466
- modalSearchClear?: string;
467
- imageSearchButton?: string;
468
417
  };
469
418
  customRenderers?: {
470
419
  Modal?: React.ComponentType<SimilarProductsModalProps>;
@@ -7,7 +7,6 @@ export const defaultSettings: Required<SimilarProductsSettings> = {
7
7
  resultsPerPage: 20,
8
8
  enableCropping: true,
9
9
  enableFileUpload: true,
10
- enableTextSearch: false,
11
10
  customStyles: {
12
11
  modal: '',
13
12
  filterSidebar: '',
@@ -16,31 +15,7 @@ export const defaultSettings: Required<SimilarProductsSettings> = {
16
15
  productItem: '',
17
16
  pagination: '',
18
17
  filterGroup: '',
19
- imageSection: '',
20
- textSearchContainer: '',
21
- textSearchLabel: '',
22
- textSearchInput: '',
23
- controlsCenter: '',
24
- modalSearchInput: '',
25
- modalSearchContainer: '',
26
- modalSearchButton: '',
27
- modalSearchIcon: '',
28
- modalSearchClearButton: '',
29
- modalSearchClearIcon: '',
30
- searchButtonIcon: '',
31
- modalCloseIcon: '',
32
- filterIcon: '',
33
- filterRemoveIcon: '',
34
- imageSearchButtonIcon: ''
35
- },
36
- iconNames: {
37
- searchButton: 'search',
38
- modalClose: 'close',
39
- filter: 'filter',
40
- filterRemove: 'close',
41
- modalSearch: 'search',
42
- modalSearchClear: 'close',
43
- imageSearchButton: 'search'
18
+ imageSection: ''
44
19
  },
45
20
  customRenderers: {
46
21
  render: {}
@@ -68,10 +43,6 @@ export function mergeSettings(
68
43
  ...defaultSettings.customStyles,
69
44
  ...userSettings.customStyles
70
45
  },
71
- iconNames: {
72
- ...defaultSettings.iconNames,
73
- ...userSettings.iconNames
74
- },
75
46
  customRenderers: {
76
47
  ...defaultSettings.customRenderers,
77
48
  ...userSettings.customRenderers,
@@ -129,19 +100,13 @@ export function validateImageFile(
129
100
  export function debounce<T extends (...args: any[]) => any>(
130
101
  func: T,
131
102
  wait: number
132
- ): ((...args: Parameters<T>) => void) & { cancel: () => void } {
103
+ ): (...args: Parameters<T>) => void {
133
104
  let timeout: NodeJS.Timeout;
134
105
 
135
- const debounced = (...args: Parameters<T>) => {
106
+ return (...args: Parameters<T>) => {
136
107
  clearTimeout(timeout);
137
108
  timeout = setTimeout(() => func(...args), wait);
138
109
  };
139
-
140
- debounced.cancel = () => {
141
- clearTimeout(timeout);
142
- };
143
-
144
- return debounced as ((...args: Parameters<T>) => void) & { cancel: () => void };
145
110
  }
146
111
 
147
112
  export function dataURLToBlob(dataURL: string): Blob {
@@ -5,8 +5,7 @@ import {
5
5
  Button,
6
6
  Icon,
7
7
  Accordion,
8
- LoaderSpinner,
9
- Input
8
+ LoaderSpinner
10
9
  } from '@akinon/next/components';
11
10
  import { useLocalization } from '@akinon/next/hooks';
12
11
  import { FilterSidebarProps } from '../types';
@@ -56,8 +55,6 @@ export function SimilarProductsFilterSidebar({
56
55
  isLoading,
57
56
  handleFacetChange,
58
57
  removeFacetFilter,
59
- searchText,
60
- setSearchText,
61
58
  currentImageUrl,
62
59
  isCropping,
63
60
  imageRef,
@@ -169,19 +166,6 @@ export function SimilarProductsFilterSidebar({
169
166
  className
170
167
  );
171
168
 
172
- const modalCloseIconClassName = twMerge(
173
- '',
174
- settings?.customStyles?.modalCloseIcon
175
- );
176
-
177
- const filterRemoveIconClassName = twMerge(
178
- '',
179
- settings?.customStyles?.filterRemoveIcon
180
- );
181
-
182
- const modalCloseIconName = settings?.iconNames?.modalClose || 'close';
183
- const filterRemoveIconName = settings?.iconNames?.filterRemove || 'close';
184
-
185
169
  return (
186
170
  <>
187
171
  {isFilterMenuOpen && (
@@ -238,11 +222,7 @@ export function SimilarProductsFilterSidebar({
238
222
  settings?.customStyles?.filterSidebarMobileCloseButton
239
223
  )}
240
224
  >
241
- <Icon
242
- name={modalCloseIconName}
243
- size={16}
244
- className={modalCloseIconClassName}
245
- />
225
+ <Icon name="close" size={16} />
246
226
  </Button>
247
227
  </div>
248
228
  <div
@@ -948,11 +928,7 @@ export function SimilarProductsFilterSidebar({
948
928
  disabled={isLoading}
949
929
  className="hover:bg-gray-200 rounded-full p-0 w-5 h-5 disabled:opacity-50 disabled:cursor-not-allowed ml-1"
950
930
  >
951
- <Icon
952
- name={filterRemoveIconName}
953
- size={10}
954
- className={filterRemoveIconClassName}
955
- />
931
+ <Icon name="close" size={10} />
956
932
  </Button>
957
933
  </div>
958
934
  ))}
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
 
3
- import React, { useState } from 'react';
3
+ import React, { useState, useRef } from 'react';
4
4
  import { Product } from '@akinon/next/types';
5
+ import { useImageSearchFeature } from '../hooks/use-image-search-feature';
5
6
  import { ImageSearchButton } from './image-search-button';
6
7
  import { SimilarProductsPlugin } from './main';
7
8
 
@@ -9,25 +10,27 @@ interface HeaderImageSearchFeatureProps {
9
10
  className?: string;
10
11
  isEnabled?: boolean;
11
12
  settings?: any;
12
- enableTextSearch?: boolean;
13
13
  }
14
14
 
15
15
  export function HeaderImageSearchFeature({
16
16
  className,
17
- isEnabled = false,
18
- settings: userSettings,
19
- enableTextSearch = false
17
+ isEnabled: isEnabledProp,
18
+ settings
20
19
  }: HeaderImageSearchFeatureProps) {
20
+ const { isEnabled: hookIsEnabled, isLoading } = useImageSearchFeature();
21
+
22
+ const envEnabled = process.env.NEXT_PUBLIC_ENABLE_IMAGE_SEARCH === 'true';
23
+ const finalIsEnabled = envEnabled
24
+ ? true
25
+ : isEnabledProp !== undefined
26
+ ? isEnabledProp
27
+ : hookIsEnabled;
28
+
21
29
  const [isImageSearchModalOpen, setIsImageSearchModalOpen] = useState(false);
22
30
  const [isResultsModalOpen, setIsResultsModalOpen] = useState(false);
23
31
  const [uploadedImageFile, setUploadedImageFile] = useState<File | null>(null);
24
32
 
25
- const settings = {
26
- ...userSettings,
27
- enableTextSearch
28
- };
29
-
30
- if (!isEnabled) {
33
+ if (isLoading || !finalIsEnabled) {
31
34
  return null;
32
35
  }
33
36
 
@@ -52,23 +55,26 @@ export function HeaderImageSearchFeature({
52
55
 
53
56
  return (
54
57
  <>
55
- <ImageSearchButton
56
- onClick={handleOpenImageSearch}
57
- className={className}
58
- settings={settings}
59
- />
60
- <SimilarProductsPlugin
61
- product={{} as Product}
62
- isOpen={isResultsModalOpen}
63
- onClose={handleResultsModalClose}
64
- activeIndex={0}
65
- showImageSearchModal={isImageSearchModalOpen}
66
- onImageSearchModalClose={handleImageSearchModalClose}
67
- uploadedImageFile={uploadedImageFile}
68
- onImageUpload={handleImageUpload}
69
- showResetButton={false}
70
- settings={settings}
71
- />
58
+ {finalIsEnabled && (
59
+ <>
60
+ <ImageSearchButton
61
+ onClick={handleOpenImageSearch}
62
+ className={className}
63
+ />
64
+ <SimilarProductsPlugin
65
+ product={{} as Product}
66
+ isOpen={isResultsModalOpen}
67
+ onClose={handleResultsModalClose}
68
+ activeIndex={0}
69
+ showImageSearchModal={isImageSearchModalOpen}
70
+ onImageSearchModalClose={handleImageSearchModalClose}
71
+ uploadedImageFile={uploadedImageFile}
72
+ onImageUpload={handleImageUpload}
73
+ showResetButton={false}
74
+ settings={settings}
75
+ />
76
+ </>
77
+ )}
72
78
  </>
73
79
  );
74
80
  }