@nyris/nyris-webapp 0.3.35 → 0.3.37

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 (57) hide show
  1. package/build/asset-manifest.json +13 -13
  2. package/build/index.html +1 -1
  3. package/build/{precache-manifest.375ac411683570ee1df5aea6de03409d.js → precache-manifest.c69fca63f2d97ff08892d42e2b903f20.js} +14 -14
  4. package/build/service-worker.js +1 -1
  5. package/build/static/css/main.41fb4769.chunk.css +2 -0
  6. package/build/static/css/main.41fb4769.chunk.css.map +1 -0
  7. package/build/static/js/2.00161cbb.chunk.js +3 -0
  8. package/build/static/js/2.00161cbb.chunk.js.map +1 -0
  9. package/build/static/js/main.09a533bd.chunk.js +3 -0
  10. package/build/static/js/main.09a533bd.chunk.js.map +1 -0
  11. package/build/static/media/error.48b946a9.svg +3 -0
  12. package/package.json +3 -3
  13. package/public/index.html +13 -0
  14. package/src/Store/search/Search.ts +4 -4
  15. package/src/Store/search/search.initialState.ts +1 -1
  16. package/src/Store/search/types.ts +1 -1
  17. package/src/common/assets/icons/arrow_left.svg +3 -0
  18. package/src/common/assets/icons/arrow_right.svg +3 -0
  19. package/src/common/assets/icons/error.svg +3 -0
  20. package/src/components/AppMobile.tsx +111 -0
  21. package/src/components/DragDropFile.tsx +5 -4
  22. package/src/components/FooterMobile.tsx +8 -2
  23. package/src/components/Header.tsx +2 -1
  24. package/src/components/HeaderMobile.tsx +5 -3
  25. package/src/components/ImageCaptureHelpModal.tsx +7 -1
  26. package/src/components/ImagePreviewMobile.tsx +87 -0
  27. package/src/components/Layout.tsx +32 -92
  28. package/src/components/ProductList/index.tsx +4 -1
  29. package/src/components/RfqBanner.tsx +120 -0
  30. package/src/components/SidePanel.tsx +147 -0
  31. package/src/components/appMobile.scss +147 -142
  32. package/src/components/drawer/cameraCustom.tsx +18 -5
  33. package/src/components/input/inputSearch.tsx +12 -7
  34. package/src/components/modal/DefaultModal.tsx +1 -1
  35. package/src/components/pre-filter/index.tsx +108 -51
  36. package/src/components/results/ItemResult.tsx +1 -1
  37. package/src/components/rfq/RfqModal.tsx +262 -0
  38. package/src/helpers/ToastHelper.ts +10 -0
  39. package/src/helpers/getCroppedCanvas.ts +26 -0
  40. package/src/hooks/useFilteredRegions.ts +37 -0
  41. package/src/index.css +0 -4
  42. package/src/page/landingPage/AppMD.tsx +0 -11
  43. package/src/page/landingPage/AppMobile.tsx +1 -0
  44. package/src/page/landingPage/common.scss +41 -58
  45. package/src/page/result/index.tsx +256 -309
  46. package/src/translations.ts +2 -2
  47. package/src/types.ts +1 -0
  48. package/src/utils.ts +0 -1
  49. package/build/static/css/main.f5a1c730.chunk.css +0 -2
  50. package/build/static/css/main.f5a1c730.chunk.css.map +0 -1
  51. package/build/static/js/2.724f4cba.chunk.js +0 -3
  52. package/build/static/js/2.724f4cba.chunk.js.map +0 -1
  53. package/build/static/js/main.f579fa9f.chunk.js +0 -3
  54. package/build/static/js/main.f579fa9f.chunk.js.map +0 -1
  55. package/build/static/media/support3.4a17f96e.svg +0 -3
  56. /package/build/static/js/{2.724f4cba.chunk.js.LICENSE.txt → 2.00161cbb.chunk.js.LICENSE.txt} +0 -0
  57. /package/build/static/js/{main.f579fa9f.chunk.js.LICENSE.txt → main.09a533bd.chunk.js.LICENSE.txt} +0 -0
@@ -6,22 +6,16 @@ import React, {
6
6
  useRef,
7
7
  useState,
8
8
  } from 'react';
9
- import { Box, Button, Typography } from '@material-ui/core';
10
- import ArrowBackIosOutlinedIcon from '@material-ui/icons/ArrowBackIosOutlined';
9
+ import { Box } from '@material-ui/core';
11
10
  import ArrowLeftIcon from '@material-ui/icons/ArrowLeft';
12
11
  import ArrowRightIcon from '@material-ui/icons/ArrowRight';
13
- import KeyboardArrowRightOutlinedIcon from '@material-ui/icons/KeyboardArrowRightOutlined';
12
+
14
13
  import { RectCoords } from '@nyris/nyris-api';
15
- import { Preview } from '@nyris/nyris-react-components';
16
- import IconSupport from 'common/assets/icons/support3.svg';
17
14
  import { CurrentRefinements } from 'components/current-refinements/current-refinements';
18
15
  import FooterResult from 'components/FooterResult';
19
16
  import CustomSearchBox from 'components/input/inputSearch';
20
17
  import ProductList from 'components/ProductList';
21
- import ExpandablePanelComponent from 'components/PanelResult';
22
18
  import { debounce, isEmpty } from 'lodash';
23
- import { ReactComponent as IconInfo } from 'common/assets/icons/info-tooltip.svg';
24
-
25
19
  import {
26
20
  Configure,
27
21
  connectStateResults,
@@ -29,7 +23,6 @@ import {
29
23
  Pagination,
30
24
  } from 'react-instantsearch-dom';
31
25
  import { useMediaQuery } from 'react-responsive';
32
- import { Link } from 'react-router-dom';
33
26
  import { feedbackRegionEpic, feedbackSuccessEpic } from 'services/Feedback';
34
27
  import { createImage, findByImage, findRegions } from 'services/image';
35
28
  import { showFeedback, showResults } from 'Store/nyris/Nyris';
@@ -49,9 +42,15 @@ import { useAppDispatch, useAppSelector } from 'Store/Store';
49
42
  import { showHits } from '../../constants';
50
43
  import { DEFAULT_REGION } from '../../constants';
51
44
  import { useTranslation } from 'react-i18next';
45
+ import RfqModal from 'components/rfq/RfqModal';
46
+ import SidePanel from 'components/SidePanel';
47
+ import useFilteredRegions from 'hooks/useFilteredRegions';
48
+ import ImagePreviewMobile from 'components/ImagePreviewMobile';
49
+ import RfqBanner from 'components/RfqBanner';
52
50
 
53
51
  interface Props {
54
52
  allSearchResults: any;
53
+ isSearchStalled?: boolean;
55
54
  }
56
55
 
57
56
  function ResultComponent(props: Props) {
@@ -64,13 +63,12 @@ function ResultComponent(props: Props) {
64
63
  requestImage,
65
64
  regions,
66
65
  selectedRegion,
67
- keyFilter,
66
+ preFilter,
68
67
  loadingSearchAlgolia,
69
68
  imageThumbSearchInput,
70
69
  } = search;
71
70
 
72
71
  const moreInfoText = settings?.productCtaText;
73
- const [toggleColLeft, setToggleColLeft] = useState<boolean>(false);
74
72
  const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
75
73
  const [imageSelection, setImageSelection] = useState<any>(null);
76
74
  const executeScroll = () => refBoxResult.current.scrollIntoView('-100px');
@@ -79,9 +77,15 @@ function ResultComponent(props: Props) {
79
77
  const [showAdjustInfo, setAdjustInfo] = useState(false);
80
78
  const [showAdjustInfoBasedOnConfidence, setShowAdjustInfoBasedOnConfidence] =
81
79
  useState(false);
82
-
80
+ const [rfqStatus, setRfqStatus] = useState<'inactive' | 'loading' | 'sent'>(
81
+ 'inactive',
82
+ );
83
+ const [isRfqModalOpen, setIsRfqModalOpen] = useState(false);
83
84
  const imageUploadRef = useRef(null);
84
-
85
+ const rfqRef = useRef<any>(null);
86
+ const [isScrolled, setIsScrolled] = useState<
87
+ 'not-scrolled' | 'scrolled' | 'user-scrolled'
88
+ >('not-scrolled');
85
89
  useEffect(() => {
86
90
  if (
87
91
  !loadingSearchAlgolia &&
@@ -104,11 +108,14 @@ function ResultComponent(props: Props) {
104
108
  useEffect(() => {
105
109
  if (selectedRegion) {
106
110
  setImageSelection(selectedRegion);
111
+ setRfqStatus('inactive');
112
+ setIsScrolled('not-scrolled');
107
113
  }
108
114
  }, [selectedRegion]);
109
115
 
110
116
  useEffect(() => {
111
117
  if (requestImage) {
118
+ setIsScrolled('not-scrolled');
112
119
  executeScroll();
113
120
  setImageSelection(DEFAULT_REGION);
114
121
  }
@@ -116,10 +123,10 @@ function ResultComponent(props: Props) {
116
123
 
117
124
  const findImageByApiNyris = useCallback(
118
125
  async (canvas: any, r?: RectCoords) => {
119
- const preFilter = [
126
+ const preFilterValues = [
120
127
  {
121
128
  key: settings.visualSearchFilterKey,
122
- values: [`${keyFilter}`],
129
+ values: Object.keys(preFilter) as string[],
123
130
  },
124
131
  ];
125
132
  dispatch(loadingActionResults());
@@ -127,7 +134,7 @@ function ResultComponent(props: Props) {
127
134
  image: canvas,
128
135
  settings,
129
136
  region: r,
130
- filters: keyFilter ? preFilter : undefined,
137
+ filters: !isEmpty(preFilter) ? preFilterValues : undefined,
131
138
  })
132
139
  .then(res => {
133
140
  dispatch(updateStatusLoading(false));
@@ -140,7 +147,7 @@ function ResultComponent(props: Props) {
140
147
  console.log('error call api change selection find image', e);
141
148
  });
142
149
  },
143
- [settings, dispatch, keyFilter],
150
+ [settings, dispatch, preFilter],
144
151
  );
145
152
 
146
153
  // TODO: Search offers for image:
@@ -195,17 +202,17 @@ function ResultComponent(props: Props) {
195
202
  dispatch(setRegions(res.regions));
196
203
  dispatch(setSelectedRegion(searchRegion));
197
204
  }
198
- const preFilter = [
205
+ const preFilterValues = [
199
206
  {
200
207
  key: settings.visualSearchFilterKey,
201
- values: [`${keyFilter}`],
208
+ values: Object.keys(preFilter) as string[],
202
209
  },
203
210
  ];
204
211
  findByImage({
205
212
  image,
206
213
  settings,
207
214
  region: searchRegion,
208
- filters: keyFilter ? preFilter : undefined,
215
+ filters: !isEmpty(preFilter) ? preFilterValues : undefined,
209
216
  }).then(res => {
210
217
  dispatch(setSearchResults(res));
211
218
  dispatch(showFeedback());
@@ -215,26 +222,30 @@ function ResultComponent(props: Props) {
215
222
  };
216
223
  const nonEmptyFilter: any[] = !requestImage
217
224
  ? []
218
- : ['sku:DOES_NOT_EXIST<score=1>'];
225
+ : ['sku:DOES_NOT_EXIST<score=1> '];
219
226
  const filterSkus: any = search?.results
220
227
  ? search?.results
221
228
  .slice()
222
229
  .reverse()
223
230
  .map((f: any, i: number) => `sku:'${f.sku}'<score=${i}> `)
224
231
  : '';
225
- const filterSkusString = [...nonEmptyFilter, ...filterSkus].join(' OR ');
232
+ const filterSkusString = [...nonEmptyFilter, ...filterSkus].join('OR ');
226
233
 
227
234
  useEffect(() => {
228
235
  document.title = 'Search results';
229
236
 
230
237
  if (requestImage || isEmpty(search.valueTextSearch.query)) return;
238
+ const preFilterValues = Object.keys(preFilter) as string[];
239
+ const filter =
240
+ preFilterValues.length > 0
241
+ ? preFilterValues
242
+ .map(item => `${settings.alogoliaFilterField}:'${item}'`)
243
+ .join(' OR ')
244
+ : '';
231
245
 
232
- const filter = keyFilter
233
- ? `${settings.alogoliaFilterField}:'${keyFilter}'`
234
- : '';
235
246
  setFilterString(filter);
236
247
  }, [
237
- keyFilter,
248
+ preFilter,
238
249
  requestImage,
239
250
  search.valueTextSearch.query,
240
251
  settings.alogoliaFilterField,
@@ -254,15 +265,25 @@ function ResultComponent(props: Props) {
254
265
 
255
266
  return () => {};
256
267
  // eslint-disable-next-line react-hooks/exhaustive-deps
257
- }, [keyFilter]);
268
+ }, [preFilter]);
258
269
 
259
270
  useEffect(() => {
260
271
  if (!requestImage) return;
261
- const filter = keyFilter
262
- ? filterSkusString
263
- ? `(${filterSkusString}) AND ${settings.alogoliaFilterField}:'${keyFilter}'`
264
- : `${settings.alogoliaFilterField}:'${keyFilter}'`
265
- : filterSkusString;
272
+
273
+ const preFilterValues = Object.keys(preFilter) as string[];
274
+ const preFilterString =
275
+ preFilterValues.length > 0
276
+ ? preFilterValues
277
+ .map(item => `${settings.alogoliaFilterField}:'${item}'`)
278
+ .join(' OR ')
279
+ : '';
280
+
281
+ const filter =
282
+ preFilterValues.length > 0
283
+ ? filterSkusString
284
+ ? `(${filterSkusString}) AND ${preFilterString}`
285
+ : preFilterString
286
+ : filterSkusString;
266
287
  setFilterString(filter);
267
288
  // eslint-disable-next-line react-hooks/exhaustive-deps
268
289
  }, [filterSkusString, settings.alogoliaFilterField]);
@@ -276,34 +297,7 @@ function ResultComponent(props: Props) {
276
297
  [findItemsInSelection, stateGlobal.search],
277
298
  );
278
299
 
279
- const filteredRegions = useMemo(
280
- () =>
281
- regions.map(
282
- (region: {
283
- normalizedRect: { x1: any; x2: any; y1: any; y2: any };
284
- }) => {
285
- if (
286
- region.normalizedRect.x1 === imageSelection.x1 &&
287
- region.normalizedRect.x2 === imageSelection.x2 &&
288
- region.normalizedRect.y1 === imageSelection.y1 &&
289
- region.normalizedRect.y2 === imageSelection.y2
290
- ) {
291
- return { ...region, show: false };
292
- }
293
- if (
294
- imageSelection.x1 === 0 &&
295
- imageSelection.x2 === 1 &&
296
- imageSelection.y1 === 0 &&
297
- imageSelection.y2 === 1
298
- ) {
299
- return { ...region, show: false };
300
- }
301
-
302
- return { ...region, show: true };
303
- },
304
- ),
305
- [imageSelection, regions],
306
- );
300
+ const filteredRegions = useFilteredRegions(regions, imageSelection);
307
301
 
308
302
  const showPostFilter = useMemo(() => {
309
303
  return settings.postFilterOption && props.allSearchResults?.hits.length > 0;
@@ -313,271 +307,224 @@ function ResultComponent(props: Props) {
313
307
  const showSidePanel = useMemo(() => {
314
308
  return requestImage || (settings.postFilterOption && showPostFilter);
315
309
  }, [showPostFilter, settings.postFilterOption, requestImage]);
310
+
311
+ useEffect(() => {
312
+ const handleScroll = () => {
313
+ setTimeout(() => {
314
+ setIsScrolled(s => (s === 'not-scrolled' ? 'scrolled' : s));
315
+ setTimeout(() => {
316
+ setIsScrolled(s => (s === 'scrolled' ? 'user-scrolled' : s));
317
+ }, 5000);
318
+ }, 1000);
319
+ };
320
+ if (requestImage)
321
+ window.addEventListener('scroll', handleScroll, { capture: true });
322
+
323
+ return () => {
324
+ window.removeEventListener('scroll', handleScroll);
325
+ };
326
+ }, [requestImage]);
327
+
316
328
  return (
317
- <div
318
- className={`wrap-main-result loading`}
319
- id="wrap-main-result"
320
- ref={refBoxResult}
321
- >
322
- <>
323
- {filterString && (
324
- <Configure
325
- query={search.valueTextSearch.query}
326
- filters={filterString}
327
- ></Configure>
328
- )}
329
- <Box className="box-wrap-result-component">
330
- {!isMobile && (
331
- <div className="box-search">
332
- <CustomSearchBox />
333
- </div>
329
+ <>
330
+ <div
331
+ className={`wrap-main-result loading`}
332
+ id="wrap-main-result"
333
+ ref={refBoxResult}
334
+ >
335
+ <>
336
+ {isRfqModalOpen && (
337
+ <RfqModal
338
+ requestImage={requestImage}
339
+ selectedRegion={selectedRegion}
340
+ setIsRfqModalOpen={setIsRfqModalOpen}
341
+ isRfqModalOpen={isRfqModalOpen}
342
+ setRfqStatus={setRfqStatus}
343
+ />
334
344
  )}
335
- <Box className="box-result">
336
- <>
337
- <Box className="btn-open-support">
338
- <Link to={'/support'} style={{ color: '#3E36DC' }}>
339
- <img src={IconSupport} alt="" width={16} height={16} />
340
- </Link>
341
- </Box>
342
- {!isMobile && (
343
- <>
344
- {showSidePanel && (
345
- <Box
346
- className={`wrap-main-col-left ${
347
- toggleColLeft ? 'toggle' : ''
348
- }`}
349
- >
350
- <Box className="box-toggle-coloumn">
351
- <Button
352
- style={{ color: '#55566b' }}
353
- onClick={() => {
354
- setToggleColLeft(!toggleColLeft);
355
- }}
356
- >
357
- {toggleColLeft ? (
358
- <KeyboardArrowRightOutlinedIcon
359
- style={{ fontSize: 30 }}
360
- />
361
- ) : (
362
- <ArrowBackIosOutlinedIcon
363
- style={{ fontSize: 20 }}
364
- />
365
- )}
366
- </Button>
367
- </Box>
368
- {settings.preview && requestImage && (
369
- <Box
370
- className="col-left"
371
- // style={{
372
- // backgroundColor: settings?.theme?.primaryColor,
373
- // }}
374
- >
375
- <Box className="box-preview">
376
- <Box
377
- className="preview-item"
378
- style={{
379
- backgroundColor: 'white',
380
- paddingTop: '40px',
381
- width: '100%',
382
- }}
383
- >
384
- <div
385
- style={{
386
- backgroundColor: '#AAABB5',
387
- width: '100%',
388
- }}
389
- >
390
- <Preview
391
- key={requestImage?.id}
392
- onSelectionChange={(r: RectCoords) => {
393
- setImageSelection(r);
394
- debouncedOnImageSelectionChange(r);
395
- }}
396
- image={requestImage?.canvas}
397
- selection={imageSelection || DEFAULT_REGION}
398
- regions={filteredRegions}
399
- maxWidth={320}
400
- maxHeight={320}
401
- dotColor={'#FBD914'}
402
- minCropWidth={60}
403
- minCropHeight={60}
404
- />
405
- </div>
406
- </Box>
407
- </Box>
408
- {(showAdjustInfoBasedOnConfidence ||
409
- showAdjustInfo) && (
410
- <Box
411
- className="box-title_col-left"
412
- alignItems="center"
413
- style={{
414
- backgroundColor: '#3E36DC',
415
- display: 'flex',
416
- columnGap: '6px',
417
- padding: '5px',
418
- }}
419
- >
420
- <IconInfo color="white" />
421
- <Typography
422
- style={{
423
- fontSize: 10,
424
- color: '#fff',
425
- }}
426
- >
427
- {showAdjustInfo
428
- ? t('crop the image for better results')
429
- : 'crop the image for better results'}
430
- </Typography>
431
- </Box>
432
- )}
433
- </Box>
434
- )}
435
- {showPostFilter && (
436
- <Box className="col-left__bottom">
437
- <ExpandablePanelComponent
438
- disjunctiveFacets={
439
- props.allSearchResults.disjunctiveFacets
440
- }
441
- />
442
- </Box>
443
- )}
345
+
346
+ {filterString && (
347
+ <Configure
348
+ query={search.valueTextSearch.query}
349
+ filters={filterString}
350
+ ></Configure>
351
+ )}
352
+ <Box className="box-wrap-result-component">
353
+ {!isMobile && (
354
+ <div className="box-search">
355
+ <CustomSearchBox />
356
+ </div>
357
+ )}
358
+ <Box className="box-result">
359
+ <>
360
+ {!isMobile && showSidePanel && (
361
+ <SidePanel
362
+ setImageSelection={setImageSelection}
363
+ allSearchResults={props.allSearchResults}
364
+ debouncedOnImageSelectionChange={
365
+ debouncedOnImageSelectionChange
366
+ }
367
+ filteredRegions={filteredRegions}
368
+ imageSelection={imageSelection}
369
+ showAdjustInfo={showAdjustInfo}
370
+ showAdjustInfoBasedOnConfidence={
371
+ showAdjustInfoBasedOnConfidence
372
+ }
373
+ showPostFilter={showPostFilter}
374
+ disjunctiveFacets={props.allSearchResults.disjunctiveFacets}
375
+ />
376
+ )}
377
+
378
+ <Box
379
+ className={`col-right ${
380
+ settings.preview && 'ml-auto mr-auto'
381
+ } ${isMobile && 'col-right-result-mobile'}`}
382
+ style={{
383
+ paddingTop: isMobile ? '16px' : '40px',
384
+ overflow: !isMobile ? 'auto' : '',
385
+ display: 'flex',
386
+ flexDirection: 'column',
387
+ }}
388
+ >
389
+ {!isMobile && (
390
+ <Box className="wrap-box-refinements">
391
+ <CurrentRefinements statusSwitchButton={true} />
444
392
  </Box>
445
393
  )}
446
- </>
447
- )}
448
-
449
- <Box
450
- className={`col-right ${
451
- settings.preview && 'ml-auto mr-auto'
452
- } ${isMobile && 'col-right-result-mobile'}`}
453
- style={{
454
- paddingTop: isMobile ? '16px' : '40px',
455
- }}
456
- >
457
- {!isMobile && (
458
- <Box className="wrap-box-refinements">
459
- <CurrentRefinements statusSwitchButton={true} />
460
- </Box>
461
- )}
462
394
 
463
- {isMobile && settings.preview && requestImage && (
395
+ {isMobile && settings.preview && requestImage && (
396
+ <ImagePreviewMobile
397
+ requestImage={requestImage}
398
+ imageSelection={imageSelection}
399
+ setImageSelection={setImageSelection}
400
+ debouncedOnImageSelectionChange={
401
+ debouncedOnImageSelectionChange
402
+ }
403
+ filteredRegions={filteredRegions}
404
+ showAdjustInfoBasedOnConfidence={
405
+ showAdjustInfoBasedOnConfidence
406
+ }
407
+ showAdjustInfo={showAdjustInfo}
408
+ />
409
+ )}
410
+
464
411
  <Box
465
- className="col-left"
466
412
  style={{
467
- backgroundColor: '#AAABB5',
468
- marginBottom: '15px',
413
+ display: 'flex',
414
+ flexDirection: 'column',
415
+ flexGrow: 1,
416
+ backgroundColor: '#FAFAFA',
469
417
  }}
470
418
  >
471
- {
472
- <Box className="box-preview">
473
- <Box
474
- className="preview-item"
475
- style={{ backgroundColor: 'white' }}
476
- >
477
- <Preview
478
- key={requestImage?.id}
479
- onSelectionChange={(r: RectCoords) => {
480
- setImageSelection(r);
481
- debouncedOnImageSelectionChange(r);
482
- }}
483
- image={requestImage?.canvas}
484
- selection={imageSelection || DEFAULT_REGION}
485
- regions={filteredRegions}
486
- maxWidth={240}
487
- maxHeight={240}
488
- dotColor={'#FBD914'}
489
- minCropWidth={60}
490
- minCropHeight={60}
419
+ <Box
420
+ className={'box-item-result ml-auto mr-auto'}
421
+ style={{ height: '100%', paddingLeft: isMobile ? 0 : 16 }}
422
+ >
423
+ <ProductList
424
+ getUrlToCanvasFile={getUrlToCanvasFile}
425
+ setLoading={false}
426
+ sendFeedBackAction={sendFeedBackAction}
427
+ moreInfoText={moreInfoText}
428
+ requestImage={requestImage}
429
+ searchQuery={search.valueTextSearch.query}
430
+ />
431
+ <Box
432
+ className="pagination-result"
433
+ style={{
434
+ width: '100%',
435
+ margin: !isMobile ? '20px auto' : '',
436
+ marginBottom:
437
+ isMobile && !requestImage ? '64px' : '20px',
438
+ padding: '0 20%',
439
+ alignSelf: 'end',
440
+ }}
441
+ >
442
+ {props.allSearchResults?.hits.length > 0 &&
443
+ (requestImage || search.valueTextSearch.query) && (
444
+ <Pagination
445
+ showFirst={false}
446
+ translations={{
447
+ previous: (
448
+ <ArrowLeftIcon style={{ color: '#161616' }} />
449
+ ),
450
+ next: (
451
+ <ArrowRightIcon
452
+ style={{ color: '#161616' }}
453
+ />
454
+ ),
455
+ }}
456
+ />
457
+ )}
458
+ </Box>
459
+
460
+ {requestImage &&
461
+ !loadingSearchAlgolia &&
462
+ !props.isSearchStalled &&
463
+ settings.rfq && (
464
+ <RfqBanner
465
+ rfqRef={rfqRef}
466
+ rfqStatus={rfqStatus}
467
+ setIsRfqModalOpen={setIsRfqModalOpen}
468
+ requestImage={requestImage}
469
+ selectedRegion={selectedRegion}
491
470
  />
492
- </Box>
493
- {(showAdjustInfoBasedOnConfidence ||
494
- showAdjustInfo) && (
471
+ )}
472
+ </Box>
473
+ </Box>
474
+ {!isMobile && props.allSearchResults?.hits?.length > 0 && (
475
+ <Box>
476
+ <Box className="box-notify">
477
+ <FooterResult search={search}>
495
478
  <Box
496
- className="box-title_col-left"
497
- alignItems="center"
498
- style={{
499
- backgroundColor: '#3E36DC',
500
- display: 'flex',
501
- columnGap: '6px',
502
- padding: '5px',
503
- width: 'fit-content',
504
- }}
479
+ display={'flex'}
480
+ style={{ padding: '0 20px' }}
481
+ className="box-change-hit-items"
505
482
  >
506
- <IconInfo color="white" />
507
- <Typography
508
- style={{
509
- fontSize: 10,
510
- color: '#fff',
511
- }}
512
- >
513
- {showAdjustInfo
514
- ? t('crop the image for better results')
515
- : 'crop the image for better results'}
516
- </Typography>
483
+ <span style={{ paddingRight: '10px' }}>
484
+ {t('Items per page')}:
485
+ </span>
486
+ <HitsPerPage
487
+ items={showHits}
488
+ defaultRefinement={20}
489
+ />
517
490
  </Box>
518
- )}
491
+ </FooterResult>
519
492
  </Box>
520
- }
521
- </Box>
522
- )}
523
-
524
- <Box className={'box-item-result ml-auto mr-auto'}>
525
- <ProductList
526
- getUrlToCanvasFile={getUrlToCanvasFile}
527
- setLoading={false}
528
- sendFeedBackAction={sendFeedBackAction}
529
- moreInfoText={moreInfoText}
530
- requestImage={requestImage}
531
- searchQuery={search.valueTextSearch.query}
532
- />
533
- <Box
534
- className="pagination-result"
535
- style={{
536
- width: '100%',
537
- margin: '20px auto',
538
- padding: '0 20%',
539
- }}
540
- >
541
- {props.allSearchResults?.hits.length > 0 &&
542
- (requestImage || search.valueTextSearch.query) && (
543
- <Pagination
544
- showFirst={false}
545
- translations={{
546
- previous: (
547
- <ArrowLeftIcon style={{ color: '#161616' }} />
548
- ),
549
- next: (
550
- <ArrowRightIcon style={{ color: '#161616' }} />
551
- ),
552
- }}
553
- />
554
- )}
555
- </Box>
493
+ </Box>
494
+ )}
556
495
  </Box>
557
- </Box>
558
- </>
559
- </Box>
560
- {!isMobile && (
561
- <Box>
562
- <Box className="box-notify">
563
- <FooterResult search={search}>
564
- <Box
565
- display={'flex'}
566
- style={{ padding: '0 20px' }}
567
- className="box-change-hit-items"
568
- >
569
- <span style={{ paddingRight: '10px' }}>
570
- {t('Items per page')}:
571
- </span>
572
- <HitsPerPage items={showHits} defaultRefinement={20} />
573
- </Box>
574
- </FooterResult>
575
- </Box>
496
+ </>
576
497
  </Box>
577
- )}
578
- </Box>
579
- </>
580
- </div>
498
+ </Box>
499
+ </>
500
+ </div>
501
+ {isScrolled === 'scrolled' &&
502
+ requestImage &&
503
+ isMobile &&
504
+ props.allSearchResults.hits.length > 0 &&
505
+ settings.rfq && (
506
+ <div
507
+ style={{
508
+ fontSize: '14px',
509
+ fontWeight: 'bold',
510
+ letterSpacing: '1.16px',
511
+ color: 'white',
512
+ borderRadius: '16px',
513
+ backgroundColor: '#4B4B4A',
514
+ boxShadow: '0px 0px 16px 0px rgba(85, 86, 107, 0.70)',
515
+ padding: '8px 16px',
516
+ zIndex: 100,
517
+ position: 'absolute',
518
+ left: '50%',
519
+ transform: 'translate(-50%, -50%)',
520
+ width: '356px',
521
+ bottom: '86px',
522
+ }}
523
+ >
524
+ Scroll down for personalized support
525
+ </div>
526
+ )}
527
+ </>
581
528
  );
582
529
  }
583
530