@nyris/nyris-webapp 0.3.90 → 0.3.92

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 (106) hide show
  1. package/build/asset-manifest.json +6 -6
  2. package/build/data/related-parts.json +83 -0
  3. package/build/index.html +1 -1
  4. package/build/js/settings.example.js +3 -0
  5. package/build/static/css/main.5ea01690.css +4 -0
  6. package/build/static/css/main.5ea01690.css.map +1 -0
  7. package/build/static/js/main.36b77705.js +3 -0
  8. package/build/static/js/{main.cede3ae1.js.map → main.36b77705.js.map} +1 -1
  9. package/package.json +4 -3
  10. package/public/data/related-parts.json +83 -0
  11. package/public/js/settings.example.js +3 -0
  12. package/src/App.test.tsx +0 -1
  13. package/src/App.tsx +0 -1
  14. package/src/assets/arrow_down_expanded.svg +3 -0
  15. package/src/assets/arrow_enter.svg +3 -0
  16. package/src/assets/camera.svg +3 -0
  17. package/src/assets/close.svg +3 -0
  18. package/src/assets/enter.svg +3 -0
  19. package/src/assets/refresh.svg +3 -0
  20. package/src/assets/vizo_avatar.svg +16 -0
  21. package/src/components/Cadenas/CadenasWebViewer.tsx +1 -1
  22. package/src/components/Cart.tsx +48 -36
  23. package/src/components/ChatAssistant/ChatAssistant.tsx +289 -0
  24. package/src/components/ChatAssistant/MobileChatAssistant.tsx +291 -0
  25. package/src/components/ChatAssistant/OptionChip.tsx +78 -0
  26. package/src/components/ChatAssistant/index.ts +3 -0
  27. package/src/components/ChatAssistant/useChatAssistantLogic.ts +745 -0
  28. package/src/components/CurrentRefinements.tsx +2 -2
  29. package/src/components/CustomCameraDrawer.tsx +56 -13
  30. package/src/components/DragDropFile.tsx +5 -5
  31. package/src/components/ExperienceVisualSearch/ExperienceVisualSearch.tsx +1 -1
  32. package/src/components/Header.tsx +116 -96
  33. package/src/components/Hint.tsx +1 -2
  34. package/src/components/HitsPerPage.tsx +9 -3
  35. package/src/components/ImagePreview.tsx +32 -17
  36. package/src/components/ImageUpload.tsx +16 -8
  37. package/src/components/Inquiry/InquiryBanner.tsx +1 -1
  38. package/src/components/Inquiry/InquiryModal.tsx +35 -29
  39. package/src/components/ItemSpecification.tsx +58 -126
  40. package/src/components/LocationInfoPopup.tsx +33 -33
  41. package/src/components/MatchNotificationBanner.tsx +90 -36
  42. package/src/components/PostFilter/PostFilter.tsx +1 -1
  43. package/src/components/PostFilter/PostFilterComponent.tsx +0 -1
  44. package/src/components/PostFilter/PostFilterFindApi.tsx +0 -1
  45. package/src/components/PoweredBy.tsx +1 -1
  46. package/src/components/PreFilter/PreFilter.tsx +14 -3
  47. package/src/components/PreFilter/PreFilterModal.tsx +0 -1
  48. package/src/components/Product/Product.tsx +15 -11
  49. package/src/components/Product/ProductAttribute.tsx +4 -5
  50. package/src/components/Product/ProductDetailViewModal.tsx +2 -4
  51. package/src/components/Product/ProductList.tsx +26 -13
  52. package/src/components/Rfq/RfqModal.tsx +1 -1
  53. package/src/components/SidePanel.tsx +124 -91
  54. package/src/components/SmartFilter.tsx +320 -0
  55. package/src/components/TextSearch.tsx +134 -70
  56. package/src/components/UploadDisclaimer.tsx +1 -1
  57. package/src/hooks/useBadResultsRecovery.ts +407 -0
  58. package/src/hooks/useEffectiveGroundingResults.ts +54 -0
  59. package/src/hooks/useGoodResultsChat.ts +651 -0
  60. package/src/hooks/useGroundedSearch.ts +88 -0
  61. package/src/hooks/useImageSearch.ts +139 -187
  62. package/src/hooks/useResultEvaluator.ts +417 -0
  63. package/src/index.css +1 -1
  64. package/src/index.tsx +0 -1
  65. package/src/layouts/AppLayout.tsx +53 -2
  66. package/src/pages/Home.tsx +11 -52
  67. package/src/pages/Login.tsx +1 -2
  68. package/src/pages/Logout.tsx +1 -1
  69. package/src/pages/Result.tsx +198 -200
  70. package/src/providers/AuthProvider.tsx +0 -1
  71. package/src/services/Feedback.ts +1 -1
  72. package/src/services/visualSearch.ts +0 -21
  73. package/src/services/vizo.ts +192 -4
  74. package/src/stores/chat/chatStore.ts +150 -0
  75. package/src/stores/chat/conversationStore.ts +300 -0
  76. package/src/stores/request/Misc/misc.slice.ts +2 -2
  77. package/src/stores/request/filter/filter.slice.ts +8 -8
  78. package/src/stores/request/query/query.slice.ts +2 -2
  79. package/src/stores/request/requestImage/requestImage.slice.ts +6 -6
  80. package/src/stores/request/specifications/specifications.slice.ts +10 -7
  81. package/src/stores/result/detectedRegions/detectedRegions.slice.ts +1 -1
  82. package/src/stores/result/prodcuts/products.initialState.ts +12 -0
  83. package/src/stores/result/prodcuts/products.slice.ts +28 -8
  84. package/src/stores/result/session/session.slice.ts +2 -2
  85. package/src/stores/smartFilters/smartFiltersStore.ts +270 -0
  86. package/src/stores/types.ts +41 -0
  87. package/src/stores/ui/ai/ai.initialState.ts +5 -0
  88. package/src/stores/ui/ai/ai.slice.ts +15 -0
  89. package/src/stores/ui/banner/banner.initialState.ts +6 -0
  90. package/src/stores/ui/banner/banner.slice.ts +14 -0
  91. package/src/stores/ui/feedback/feedback.slice.ts +1 -1
  92. package/src/stores/ui/loading/loading.slice.ts +4 -4
  93. package/src/stores/ui/uiStore.ts +7 -1
  94. package/src/styles/product.scss +0 -2
  95. package/src/types.ts +3 -7
  96. package/src/utils/cropImageToBase64.ts +32 -0
  97. package/src/utils/fetchProductImage.ts +109 -0
  98. package/src/utils/imageConverters.ts +124 -0
  99. package/src/utils/relatedParts.ts +35 -0
  100. package/src/utils/specificationFilter.ts +1 -5
  101. package/tailwind.config.js +3 -2
  102. package/build/static/css/main.734b52e1.css +0 -4
  103. package/build/static/css/main.734b52e1.css.map +0 -1
  104. package/build/static/js/main.cede3ae1.js +0 -3
  105. package/src/utils/addAssets.ts +0 -40
  106. /package/build/static/js/{main.cede3ae1.js.LICENSE.txt → main.36b77705.js.LICENSE.txt} +0 -0
@@ -26,11 +26,14 @@ import { useCurrentRefinements } from 'react-instantsearch';
26
26
  import CustomCamera from 'components/CustomCameraDrawer';
27
27
  import { useTranslation } from 'react-i18next';
28
28
  import { useImageSearch } from 'hooks/useImageSearch';
29
- import ItemSpecification from 'components/ItemSpecification';
30
29
  import MatchNotificationBanner from 'components/MatchNotificationBanner';
30
+ import ImageUpload from 'components/ImageUpload';
31
+ import SmartFilter from 'components/SmartFilter';
32
+ import { ChatAssistant, MobileChatAssistant } from 'components/ChatAssistant';
31
33
 
32
34
  function Results() {
33
35
  const settings = window.settings;
36
+ const isSmartFiltersEnabled = !!settings.useSmartFilters;
34
37
  const cadenas = settings.cadenas;
35
38
 
36
39
  const [feedbackStatus, setFeedbackStatus] = useState<
@@ -50,6 +53,7 @@ function Results() {
50
53
  const setShowFeedback = useUiStore(state => state.setShowFeedback);
51
54
  const showFeedback = useUiStore(state => state.showFeedback);
52
55
  const setIsFindApiLoading = useUiStore(state => state.setIsFindApiLoading);
56
+ const isAiModeOpen = useUiStore(state => state.isAiModeOpen);
53
57
 
54
58
  const requestId = useResultStore(state => state.requestId);
55
59
  const imageAnalysis = useResultStore(state => state.imageAnalysis);
@@ -169,6 +173,10 @@ function Results() {
169
173
  ]);
170
174
 
171
175
  const disablePostFilter = useMemo(() => {
176
+ if (!settings.algolia.enabled) {
177
+ return false;
178
+ }
179
+
172
180
  return settings.postFilterOption && productsFromAlgolia.length > 0
173
181
  ? false
174
182
  : true;
@@ -183,245 +191,218 @@ function Results() {
183
191
  <Loading />
184
192
  </div>
185
193
  )}
186
- <div className="h-full">
194
+ <div className="h-full overflow-y-auto overflow-x-hidden desktop:overflow-hidden">
187
195
  <div
188
196
  className={twMerge([
189
197
  'flex',
190
198
  'flex-col',
191
199
  'desktop:flex-row',
192
- 'justify-between',
193
- 'relative',
194
200
  'h-full',
201
+ 'desktop:min-h-0',
195
202
  ])}
196
203
  >
197
- <SidePanel className="hidden desktop:flex" />
198
-
199
- <div className="w-full h-full flex flex-col">
200
- <div
201
- className={twMerge([
202
- requestImages[0] ? 'pt-0' : 'pt-3',
203
- 'desktop:pt-0',
204
- 'desktop:mt-0',
205
- 'flex',
206
- 'flex-col',
207
- 'relative',
208
- 'w-full',
209
- 'mr-auto',
210
- 'ml-auto',
211
- 'max-h-full',
212
- 'flex-1',
213
- 'overflow-y-auto',
214
- ])}
215
- >
216
- <div className="block desktop:hidden desktop:mb-0">
217
- {requestImages[0] && <ImagePreview />}
218
- {window.settings.showImageDetails &&
219
- (imageAnalysis?.imageDescription ||
220
- Object.keys(imageAnalysis?.specification || {}).length >
221
- 0) && (
222
- <div className="p-2">
223
- <div className="self-stretch p-4 bg-[#f3f3f5] rounded flex justify-start flex-col items-start gap-2 flex-wrap content-start w-full">
224
- {imageAnalysis?.imageDescription !==
225
- 'No description available' && (
226
- <div className="self-stretch flex flex-col justify-start items-start">
227
- <div className="justify-start text-black text-base font-semibold">
228
- Image description
229
- </div>
230
- <div className="self-stretch justify-start text-black text-sm font-normal">
231
- {imageAnalysis?.imageDescription || ''}
232
- </div>
233
- </div>
234
- )}
235
-
236
- {Object.keys(imageAnalysis?.specification || {})
237
- .filter(
238
- key =>
239
- key !== 'is_nameplate' &&
240
- key !== 'prefilter_value',
241
- )
242
- .some(key => !!imageAnalysis?.specification[key]) && (
243
- <div className="justify-start text-[#2b2c46] text-base font-semibold mt-1">
244
- Identified Attributes
245
- </div>
246
- )}
247
- <div className="flex justify-start items-start gap-4 flex-wrap content-start">
248
- {Object.keys(imageAnalysis?.specification || {})
249
- .filter(
250
- key =>
251
- key !== 'is_nameplate' &&
252
- key !== 'prefilter_value',
253
- )
254
- .map(key => {
255
- const value = imageAnalysis?.specification[key];
256
- if (!value) {
257
- return null;
258
- }
259
- return (
260
- <ItemSpecification
261
- attr={key}
262
- value={value}
263
- specificationFilter={specificationFilter}
264
- imageAnalysis={imageAnalysis}
265
- />
266
- );
267
- })}
268
- </div>
269
- </div>
270
- </div>
271
- )}
272
- </div>
204
+ <SidePanel className="hidden desktop:flex h-full max-h-full min-h-0" />
205
+ {/* Scrollable area: results + sticky chat. Scrollbar lands at far right. */}
206
+ <div className="flex-1 flex flex-col desktop:flex-row desktop:h-full desktop:min-h-0 desktop:overflow-y-auto">
207
+ {/* Result content */}
208
+ <div className="w-full min-h-full flex flex-col desktop:min-h-0 flex-1">
273
209
  <div
274
210
  className={twMerge([
275
- requestImages[0] ? 'pt-0' : 'pt-3',
276
- 'desktop:pt-4',
277
- 'desktop:overflow-hidden',
278
- 'desktop:overflow-y-auto',
211
+ requestImages[0] && 'pt-0',
212
+ 'desktop:pt-0',
213
+ 'desktop:mt-0',
279
214
  'flex',
280
215
  'flex-col',
281
216
  'relative',
282
217
  'w-full',
283
218
  'mr-auto',
284
219
  'ml-auto',
285
- 'h-full',
220
+ 'flex-1',
286
221
  ])}
287
222
  >
223
+ <div className="block desktop:hidden desktop:mb-0 mx-2">
224
+ {requestImages[0] && <ImagePreview />}
225
+ {isSmartFiltersEnabled &&
226
+ window.settings.showImageDetails &&
227
+ (imageAnalysis?.imageDescription ||
228
+ Object.keys(imageAnalysis?.specification || {}).length >
229
+ 0) && (
230
+ <div className="my-4">
231
+ <SmartFilter
232
+ imageAnalysis={imageAnalysis}
233
+ specificationFilter={specificationFilter}
234
+ />
235
+ </div>
236
+ )}
237
+ </div>
288
238
  <div
289
239
  className={twMerge([
240
+ requestImages[0] && 'pt-0',
241
+ 'desktop:pt-4',
290
242
  'flex',
291
243
  'flex-col',
244
+ 'relative',
245
+ 'w-full',
246
+ 'mr-auto',
247
+ 'ml-auto',
292
248
  'flex-grow',
293
- 'desktop:mt-0',
294
249
  ])}
295
250
  >
296
- <div
297
- style={{
298
- fontWeight: 700,
299
- fontSize: 16,
300
- marginLeft: 16,
301
- marginBottom: 16,
302
- }}
303
- >
304
- {!specifications?.specificationPrefilter &&
305
- specifications?.prefilter_value &&
306
- window.settings.algolia.enabled &&
307
- t('Showing results for machine', {
308
- prefilter_title:
309
- window.settings.preFilterTitle?.toLocaleLowerCase(),
310
- prefilter_value: specifications.prefilter_value,
311
- })}
312
- </div>
313
251
  <div
314
252
  className={twMerge([
315
- 'h-full',
316
- 'relative',
317
253
  'flex',
318
- 'justify-center',
319
- 'mx-0.5',
320
- 'mobile-md:mx-2',
321
- 'desktop:mx-4',
254
+ 'flex-col',
255
+ 'flex-grow',
256
+ 'desktop:mt-0',
322
257
  ])}
323
258
  >
324
- <div className="max-w-[840px] w-full relative flex flex-col justify-between mb-20 desktop:mb-0">
325
- <div
326
- className={twMerge(
327
- 'grid grid-cols-[repeat(auto-fit,_minmax(180px,_0px))] desktop:grid-cols-[repeat(auto-fit,_minmax(190px,_0px))]',
328
- 'gap-2 desktop:gap-6 justify-center max-w-[100%] mx-auto',
329
- 'w-full',
330
- )}
331
- >
332
- <GoBackButton className="col-span-full mb-2 desktop:mb-0" />
333
- <CurrentRefinements className="col-span-full" />
334
- <MatchNotificationBanner className="col-span-full" />
335
- <ProductList />
336
- </div>
337
-
338
- {showFeedbackSuccess && (
339
- <div className={'feedback-floating'}>
340
- <div className="feedback-section">
341
- <div className="feedback-success">
342
- {t('Thank you for your feedback')}
343
- </div>
344
- </div>
259
+ {!specifications?.specificationPrefilter &&
260
+ specifications?.prefilter_value &&
261
+ window.settings.algolia.enabled && (
262
+ <div
263
+ style={{
264
+ fontWeight: 700,
265
+ fontSize: 16,
266
+ marginLeft: 16,
267
+ marginBottom: 16,
268
+ }}
269
+ >
270
+ {t('Showing results for machine', {
271
+ prefilter_title:
272
+ window.settings.preFilterTitle?.toLocaleLowerCase(),
273
+ prefilter_value: specifications.prefilter_value,
274
+ })}
345
275
  </div>
346
276
  )}
277
+ <div
278
+ className={twMerge([
279
+ 'relative',
280
+ 'flex',
281
+ 'justify-center',
282
+ 'mx-0.5',
283
+ 'mobile-md:mx-2',
284
+ 'desktop:mx-4',
285
+ ])}
286
+ >
287
+ <div className="max-w-[840px] w-full relative flex flex-col justify-between mb-20 desktop:mb-0">
288
+ <div
289
+ className={twMerge(
290
+ 'grid grid-cols-[repeat(auto-fit,_minmax(180px,_0px))] desktop:grid-cols-[repeat(auto-fit,_minmax(190px,_0px))]',
291
+ 'gap-2 desktop:gap-6 justify-center max-w-[100%] mx-auto',
292
+ 'w-full',
293
+ )}
294
+ >
295
+ <GoBackButton className="col-span-full mb-2 desktop:mb-0 mt-2 desktop:mt-0" />
296
+ <CurrentRefinements className="col-span-full" />
297
+ <MatchNotificationBanner className="col-span-full" />
298
+ <ProductList />
299
+ </div>
347
300
 
348
- {feedbackStatus === 'visible' &&
349
- !showFeedbackSuccess &&
350
- productsFromAlgolia.length > 0 && (
301
+ {showFeedbackSuccess && (
351
302
  <div className={'feedback-floating'}>
352
- <div className="feedback-section feedback-backdrop-blur" />
353
-
354
303
  <div className="feedback-section">
355
- <Feedback
356
- submitFeedback={submitFeedback}
357
- onFeedbackClose={() => {
358
- setFeedbackStatus('submitted');
359
- setShowFeedback(false);
360
- }}
361
- />
304
+ <div className="feedback-success">
305
+ {t('Thank you for your feedback')}
306
+ </div>
362
307
  </div>
363
308
  </div>
364
309
  )}
365
- <div>
366
- <Pagination
367
- isLoading={isFindApiLoading || isAlgoliaLoading}
368
- className={
369
- productsFromAlgolia.length === 0 &&
370
- !isAlgoliaLoading
371
- ? 'opacity-0'
372
- : ''
373
- }
374
- />
375
- <div
376
- style={{
377
- display: 'flex',
378
- flexGrow: 1,
379
- }}
380
- >
381
- {requestImages.length > 0 &&
382
- !isAlgoliaLoading &&
383
- !isFindApiLoading &&
384
- window.settings.rfq &&
385
- window.settings.rfq.enabled && (
386
- <RfqBanner
387
- requestImage={requestImages[0]}
388
- selectedRegion={regions[0]}
389
- />
390
- )}
391
- {!isFindApiLoading &&
392
- window.settings.support &&
393
- window.settings.support.enabled &&
394
- (query || requestImages[0] || specifications) && (
395
- <InquiryBanner
396
- requestImage={requestImages[0]}
397
- selectedRegion={regions[0]}
398
- query={query}
399
- />
400
- )}
401
- </div>
402
- {settings.showPoweredByNyris && (
403
- <PoweredBy
310
+
311
+ {feedbackStatus === 'visible' &&
312
+ !showFeedbackSuccess &&
313
+ productsFromAlgolia.length > 0 && (
314
+ <div className={'feedback-floating'}>
315
+ <div className="feedback-section feedback-backdrop-blur" />
316
+
317
+ <div className="feedback-section">
318
+ <Feedback
319
+ submitFeedback={submitFeedback}
320
+ onFeedbackClose={() => {
321
+ setFeedbackStatus('submitted');
322
+ setShowFeedback(false);
323
+ }}
324
+ />
325
+ </div>
326
+ </div>
327
+ )}
328
+ <div>
329
+ <Pagination
330
+ isLoading={isFindApiLoading || isAlgoliaLoading}
404
331
  className={
405
- 'flex desktop:w-0 desktop:h-0 w-full justify-center items-center mb-2'
332
+ productsFromAlgolia.length === 0 &&
333
+ !isAlgoliaLoading
334
+ ? 'opacity-0 hidden'
335
+ : ''
406
336
  }
407
337
  />
408
- )}
338
+ <div
339
+ style={{
340
+ display: 'flex',
341
+ flexGrow: 1,
342
+ }}
343
+ >
344
+ {requestImages.length > 0 &&
345
+ !isAlgoliaLoading &&
346
+ !isFindApiLoading &&
347
+ window.settings.rfq &&
348
+ window.settings.rfq.enabled && (
349
+ <RfqBanner
350
+ requestImage={requestImages[0]}
351
+ selectedRegion={regions[0]}
352
+ />
353
+ )}
354
+ {!isFindApiLoading &&
355
+ window.settings.support &&
356
+ window.settings.support.enabled &&
357
+ (query || requestImages[0] || specifications) && (
358
+ <InquiryBanner
359
+ requestImage={requestImages[0]}
360
+ selectedRegion={regions[0]}
361
+ query={query}
362
+ />
363
+ )}
364
+ </div>
365
+ {settings.showPoweredByNyris && (
366
+ <PoweredBy
367
+ className={
368
+ 'flex desktop:w-0 desktop:h-0 w-full justify-center items-center mb-2'
369
+ }
370
+ />
371
+ )}
372
+ </div>
409
373
  </div>
410
374
  </div>
411
375
  </div>
376
+ <div className="mt-[6px] px-6 mb-6">
377
+ <HitsPerPage
378
+ items={[
379
+ { label: '10', value: 10 },
380
+ { label: '20', value: 20, default: true },
381
+ { label: '30', value: 30 },
382
+ { label: '40', value: 40 },
383
+ { label: '50', value: 50 },
384
+ ]}
385
+ />
386
+ </div>
412
387
  </div>
413
388
  </div>
414
- <div className="mt-[6px]">
415
- <HitsPerPage
416
- items={[
417
- { label: '10', value: 10 },
418
- { label: '20', value: 20, default: true },
419
- { label: '30', value: 30 },
420
- { label: '40', value: 40 },
421
- { label: '50', value: 50 },
422
- ]}
423
- />
424
- </div>
389
+ </div>
390
+
391
+ <div
392
+ className={twMerge(
393
+ 'hidden desktop:flex flex-col sticky top-0 self-start',
394
+ 'overflow-hidden transition-all duration-300',
395
+ 'h-screen max-h-full',
396
+ isAiModeOpen
397
+ ? 'w-[325px] min-w-[325px] max-w-[325px]'
398
+ : 'w-0 min-w-0 max-w-0',
399
+ 'rounded-3xl',
400
+
401
+ isAiModeOpen && 'pb-4 pr-4',
402
+ 'shadow-ds-2',
403
+ )}
404
+ >
405
+ <ChatAssistant />
425
406
  </div>
426
407
  </div>
427
408
  </div>
@@ -430,20 +411,24 @@ function Results() {
430
411
  <TextSearch
431
412
  className="flex desktop:hidden w-full gap-2"
432
413
  onCameraClick={() => setOpenModalCamera(true)}
414
+ showImageUpload={false}
415
+ aiMode={true}
433
416
  />
434
- {/* <ImageUpload onCameraClick={() => setOpenModalCamera(true)} /> */}
417
+
435
418
  {isShowFilter && settings.postFilterOption && (
436
419
  <div
437
420
  style={{
438
421
  position: 'relative',
439
- width: '48px',
440
- height: '48px',
441
422
  padding: ' 8px',
442
423
  flexShrink: 0,
443
424
  borderRadius: '32px',
444
425
  background: '#FAFAFA',
445
- boxShadow: ' 0px 0px 8px 0px rgba(0, 0, 0, 0.15)',
446
426
  }}
427
+ className={twMerge(
428
+ 'h-14 min-w-14 flex items-center justify-center ',
429
+ 'border border-solid border-[#DDDEE7]',
430
+ 'shadow-ds-2',
431
+ )}
447
432
  onClick={() => {
448
433
  if (disablePostFilter && !isPostFilterApplied) return;
449
434
  setShowPostFilter(true);
@@ -462,8 +447,8 @@ function Results() {
462
447
  : '#F3F3F5'
463
448
  }`,
464
449
  borderRadius: '40px',
465
- width: '32px',
466
- height: '32px',
450
+ width: '40px',
451
+ height: '40px',
467
452
  justifyContent: 'center',
468
453
  alignItems: 'center',
469
454
  }}
@@ -513,6 +498,14 @@ function Results() {
513
498
  )}
514
499
  </div>
515
500
  )}
501
+ <div
502
+ className={twMerge(
503
+ 'h-14 min-w-14 flex items-center justify-center rounded-full bg-[#FFFFFF] border border-solid border-[#DDDEE7]',
504
+ 'shadow-ds-2',
505
+ )}
506
+ >
507
+ <ImageUpload onCameraClick={() => setOpenModalCamera(true)} />
508
+ </div>
516
509
  </div>
517
510
  <PostFilterDrawer
518
511
  openModal={showPostFilter}
@@ -524,6 +517,11 @@ function Results() {
524
517
  setOpenModalCamera(s => !s);
525
518
  }}
526
519
  />
520
+ {isAiModeOpen && (
521
+ <div className="desktop:hidden">
522
+ <MobileChatAssistant />
523
+ </div>
524
+ )}
527
525
  </div>
528
526
  </>
529
527
  );
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import { Auth0Provider } from '@auth0/auth0-react';
3
2
 
4
3
  const AuthProvider = ({ children }: any) => {
@@ -65,7 +65,7 @@ export const sendFeedbackByApi = async (
65
65
  const api = new NyrisAPI(settings);
66
66
  if (requestId) {
67
67
  try {
68
- await api.sendFeedback({ sessionId, requestId, payload }).then(res => {});
68
+ await api.sendFeedback({ sessionId, requestId, payload }).then(() => {});
69
69
  } catch (error) {
70
70
  console.log('error sendFeedbackByApi', error);
71
71
  }
@@ -85,34 +85,13 @@ export const find = async ({
85
85
  return nyrisApi.find(options, image, filters);
86
86
  };
87
87
 
88
- export const findMulti = ({
89
- images,
90
- settings,
91
- regions,
92
- filters,
93
- text,
94
- }: {
95
- images?: HTMLCanvasElement[];
96
- settings: NyrisAPISettings;
97
- regions?: RectCoords[];
98
- filters?: Filter[];
99
- text?: string;
100
- }) => {
101
- const nyrisApi = new NyrisAPI(settings);
102
- let options: ImageSearchOptions = text ? { text } : {};
103
-
104
- return nyrisApi.findMulti(options, images, regions, filters);
105
- };
106
-
107
88
  export const findCad = ({
108
89
  file,
109
- options,
110
90
  settings,
111
91
  filters,
112
92
  }: {
113
93
  file: File;
114
94
  settings: NyrisAPISettings;
115
- options?: ImageSearchOptions;
116
95
  filters?: Filter[];
117
96
  }) => {
118
97
  const nyrisApi = new NyrisAPI(settings);