@nyris/nyris-webapp 0.3.69 → 0.3.71

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 (33) hide show
  1. package/.env +1 -0
  2. package/build/asset-manifest.json +10 -6
  3. package/build/index.html +1 -1
  4. package/build/js/settings.example.js +8 -0
  5. package/build/static/css/main.1c4bd450.css +4 -0
  6. package/build/static/css/main.1c4bd450.css.map +1 -0
  7. package/build/static/js/906.26c8485c.chunk.js +2 -0
  8. package/build/static/js/906.26c8485c.chunk.js.map +1 -0
  9. package/build/static/js/95.c359f13c.chunk.js +2 -0
  10. package/build/static/js/95.c359f13c.chunk.js.map +1 -0
  11. package/build/static/js/main.eb837239.js +3 -0
  12. package/build/static/js/{main.bbe06da4.js.map → main.eb837239.js.map} +1 -1
  13. package/package.json +6 -3
  14. package/public/js/settings.example.js +8 -0
  15. package/src/components/DragDropFile.tsx +1 -3
  16. package/src/components/Experience-visual-search/ExperienceVisualSearch.tsx +33 -22
  17. package/src/components/Feedback.tsx +4 -1
  18. package/src/components/ImagePreview.tsx +3 -2
  19. package/src/components/Inquiry/InquiryBanner.tsx +2 -2
  20. package/src/components/Inquiry/InquiryModal.tsx +20 -16
  21. package/src/components/ProductDetailView.tsx +93 -35
  22. package/src/components/UploadDisclaimer.tsx +14 -11
  23. package/src/components/drawer/cameraCustom.tsx +3 -5
  24. package/src/components/input/inputSearch.tsx +4 -2
  25. package/src/components/rfq/RfqBanner.tsx +5 -4
  26. package/src/hooks/useImageSearch.ts +27 -4
  27. package/src/page/result/index.tsx +1 -1
  28. package/src/translations.ts +92 -10
  29. package/src/types.ts +7 -0
  30. package/build/static/css/main.05cedda2.css +0 -4
  31. package/build/static/css/main.05cedda2.css.map +0 -1
  32. package/build/static/js/main.bbe06da4.js +0 -3
  33. /package/build/static/js/{main.bbe06da4.js.LICENSE.txt → main.eb837239.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "name": "@nyris/nyris-webapp",
3
- "version": "0.3.69",
3
+ "version": "0.3.71",
4
4
  "dependencies": {
5
5
  "@auth0/auth0-react": "^2.2.4",
6
6
  "@emailjs/browser": "^4.3.3",
7
7
  "@material-ui/core": "^4.12.4",
8
8
  "@material-ui/icons": "^4.11.3",
9
9
  "@material-ui/lab": "^4.0.0-alpha.61",
10
- "@nyris/nyris-api": "^0.3.69",
11
- "@nyris/nyris-react-components": "^0.3.69",
10
+ "@nyris/nyris-api": "^0.3.71",
11
+ "@nyris/nyris-react-components": "^0.3.71",
12
12
  "@reduxjs/toolkit": "^2.2.1",
13
13
  "@splidejs/react-splide": "^0.7.12",
14
14
  "@testing-library/jest-dom": "^5.17.0",
15
15
  "@testing-library/react": "^13.4.0",
16
16
  "@testing-library/user-event": "^13.5.0",
17
+ "@types/heic-convert": "^2.1.0",
17
18
  "@types/jest": "^27.5.2",
18
19
  "@types/node": "^16.18.88",
19
20
  "@types/react": "^18.2.65",
@@ -23,7 +24,9 @@
23
24
  "blueimp-load-image": "^5.16.0",
24
25
  "classnames": "^2.5.1",
25
26
  "compressorjs": "^1.2.1",
27
+ "env": "^0.0.2",
26
28
  "framer-motion": "^11.0.12",
29
+ "heic-convert": "^2.1.0",
27
30
  "i18next": "^23.10.1",
28
31
  "jotai": "^1.4.7",
29
32
  "jquery": "^3.7.1",
@@ -71,6 +71,13 @@ var settings = {
71
71
  CTALinkField: '',
72
72
  },
73
73
  language: 'en',
74
+ // productDetailsAttribute
75
+ productDetailsAttribute: [
76
+ {
77
+ propertyName: '',
78
+ value: '',
79
+ }
80
+ ],
74
81
  // features
75
82
  showPoweredByNyris: '',
76
83
  postFilterOption: '',
@@ -90,6 +97,7 @@ var settings = {
90
97
  emailTemplateId: '',
91
98
  supportNumber: '',
92
99
  description: '',
100
+ prefilterFieldName: '',
93
101
  },
94
102
  cadenas: {
95
103
  catalog: '',
@@ -95,9 +95,7 @@ function DragDropFile(props: Props) {
95
95
  className="inputFile"
96
96
  placeholder="Choose photo"
97
97
  style={{ display: 'block', cursor: 'pointer' }}
98
- accept={`${
99
- isCadSearch ? '.stp,.step,.stl,.obj,.glb,.gltf,' : ''
100
- }image/*`}
98
+ accept={'.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,image/*'}
101
99
  />
102
100
  </div>
103
101
  </div>
@@ -11,6 +11,7 @@ import {
11
11
  import { useImageSearch } from 'hooks/useImageSearch';
12
12
  import { useHistory } from 'react-router-dom';
13
13
  import { Icon } from '@nyris/nyris-react-components';
14
+ import { useTranslation } from 'react-i18next';
14
15
 
15
16
  function ExperienceVisualSearch({
16
17
  experienceVisualSearchBlobs,
@@ -26,28 +27,26 @@ function ExperienceVisualSearch({
26
27
 
27
28
  const { singleImageSearch } = useImageSearch();
28
29
 
30
+ const { t } = useTranslation();
31
+
32
+ const [expand, setExpand] = useState(false);
33
+
29
34
  useEffect(() => {
35
+ let intervalId: any;
30
36
  if (document.body.getBoundingClientRect().width >= 776) {
31
37
  if (!showModal) {
32
- interval.current = setInterval(() => {
33
- if (button?.current) {
34
- (button.current as HTMLElement).classList.toggle('hover');
35
- }
38
+ intervalId = setInterval(() => {
39
+ setExpand(s => !s);
36
40
  }, 3000);
37
41
  } else if (interval?.current) {
38
42
  clearInterval(interval?.current);
39
- if (
40
- button?.current &&
41
- !(button.current as HTMLElement).classList.contains('hover')
42
- ) {
43
- (button.current as HTMLElement).classList.toggle('hover');
44
- }
43
+ setExpand(false);
45
44
  }
46
45
  return () => {
47
- if (interval?.current) {
48
- clearInterval(interval?.current);
49
- }
46
+ clearInterval(intervalId);
50
47
  };
48
+ } else {
49
+ setExpand(true);
51
50
  }
52
51
  }, [showModal]);
53
52
 
@@ -72,13 +71,25 @@ function ExperienceVisualSearch({
72
71
 
73
72
  return (
74
73
  <>
75
- <div
76
- ref={button}
77
- className="experience-visual-button"
78
- onClick={() => modalToggle(true)}
79
- >
80
- <span />
81
- <ExperienceIcon />
74
+ <div className="flex flex-col items-center">
75
+ <div
76
+ ref={button}
77
+ className={`group bg-[#3E36DC] w-[215px] desktop:w-10 hover:w-[215px] hover:gap-2 ${
78
+ expand ? 'desktop:w-[215px] gap-2' : ''
79
+ } h-10 flex flex-row justify-center items-center rounded-full cursor-pointer my-8 transition-all duration-300`}
80
+ onClick={() => modalToggle(true)}
81
+ >
82
+ <span
83
+ className={`${
84
+ expand ? 'flex-grow max-w-fit' : 'flex-grow-0 w-0'
85
+ } group-hover:flex-grow group-hover:max-w-fit overflow-hidden whitespace-nowrap text-sm font-semibold leading-4 text-center text-white break-keep transition-all duration-300`}
86
+ >
87
+ {t('Experience Visual Search')}
88
+ </span>
89
+ <div className="flex flex-grow-0">
90
+ <ExperienceIcon className="" />
91
+ </div>
92
+ </div>
82
93
  </div>
83
94
  {showModal &&
84
95
  createPortal(
@@ -104,10 +115,10 @@ function ExperienceVisualSearch({
104
115
  }}
105
116
  />
106
117
  <div className="custom-modal-body-title">
107
- Experience Visual Search
118
+ {t('Experience Visual Search')}
108
119
  </div>
109
120
  <div className="custom-modal-body-subtitle">
110
- Start your visual search by selecting an image below.
121
+ {t('Start your visual search by selecting an image below.')}
111
122
  </div>
112
123
  <div className="custom-modal-body-content experience-visual-search-images">
113
124
  {new Array(4).fill(1).map((val, index) => {
@@ -1,5 +1,6 @@
1
1
  import { Icon } from '@nyris/nyris-react-components';
2
2
  import { useState } from 'react';
3
+ import { useTranslation } from 'react-i18next';
3
4
 
4
5
  function Feedback({
5
6
  submitFeedback,
@@ -10,6 +11,8 @@ function Feedback({
10
11
  }) {
11
12
  const [isHovered, setIsHovered] = useState(false);
12
13
 
14
+ const { t } = useTranslation();
15
+
13
16
  return (
14
17
  <div
15
18
  className={`feedback-wrapper`}
@@ -18,7 +21,7 @@ function Feedback({
18
21
  transition: 'background-color 0.3s ease',
19
22
  }}
20
23
  >
21
- <p className="desktop:w-[146px]">Are these results useful?</p>
24
+ <p className="desktop:w-[146px]">{t('Are these results useful?')}</p>
22
25
  <div
23
26
  className="feedback-icon-wrapper"
24
27
  onClick={() => submitFeedback(false)}
@@ -294,6 +294,7 @@ function ImagePreviewComponent({
294
294
  borderRadius: '16px',
295
295
  zIndex: 1000,
296
296
  height: 'fit-content',
297
+ alignItems: 'center',
297
298
  }}
298
299
  >
299
300
  <Icon name="info" color="white" width={12} height={12} />
@@ -306,7 +307,7 @@ function ImagePreviewComponent({
306
307
  >
307
308
  {showAdjustInfo
308
309
  ? t('Crop the image for better results')
309
- : 'Crop the image for better results'}
310
+ : t('Adjust the selection frame for better results')}
310
311
  </p>
311
312
  </div>
312
313
  )}
@@ -396,7 +397,7 @@ function ImagePreviewComponent({
396
397
  >
397
398
  {showAdjustInfo
398
399
  ? t('Crop the image for better results')
399
- : 'Crop the image for better results'}
400
+ : t('Adjust the selection frame for better results')}
400
401
  </p>
401
402
  </div>
402
403
  )}
@@ -155,7 +155,7 @@ function InquiryBanner({
155
155
  justifyContent: 'space-between',
156
156
  }}
157
157
  >
158
- <p>Inquiry</p>
158
+ <p>{t('Inquiry')}</p>
159
159
  <Icon name="email" color="#fff" width={16} height={12} />
160
160
  </div>
161
161
  </div>
@@ -190,7 +190,7 @@ function InquiryBanner({
190
190
  justifyContent: 'space-between',
191
191
  }}
192
192
  >
193
- <p> Call us</p>
193
+ <p> {t('Call us')}</p>
194
194
  <Icon name="call" color="#fff" width={16} height={16} />
195
195
  </div>
196
196
  </a>
@@ -11,6 +11,7 @@ import toast from 'react-hot-toast';
11
11
  import { useAppSelector } from 'Store/Store';
12
12
  import { useMediaQuery } from 'react-responsive';
13
13
  import { Icon } from '@nyris/nyris-react-components';
14
+ import { useTranslation } from 'react-i18next';
14
15
  interface Props {
15
16
  requestImage: any;
16
17
  selectedRegion: any;
@@ -60,6 +61,7 @@ export default function InquiryModal({
60
61
  },
61
62
  [setInformation],
62
63
  );
64
+ const { t } = useTranslation();
63
65
 
64
66
  useEffect(() => emailjs.init('SMGihPnuEGcYLm0V4'), []);
65
67
  useEffect(() => {
@@ -173,8 +175,8 @@ export default function InquiryModal({
173
175
  }}
174
176
  >
175
177
  {requestImage
176
- ? 'Submit your image for inquiry'
177
- : 'Submit your inquiry'}
178
+ ? t('Submit your image for inquiry')
179
+ : t('Submit your inquiry')}
178
180
  </p>
179
181
  <div
180
182
  onClick={() => setIsInquiryModalOpen(false)}
@@ -223,7 +225,7 @@ export default function InquiryModal({
223
225
  marginBottom: '8px',
224
226
  }}
225
227
  >
226
- Your email (required)
228
+ {t('Your email (required)')}
227
229
  </p>
228
230
  <input
229
231
  value={email}
@@ -239,7 +241,7 @@ export default function InquiryModal({
239
241
  />
240
242
  {!emailValid && !isUndefined(emailValid) && (
241
243
  <p style={{ color: 'red', fontSize: '12px', paddingTop: '8px' }}>
242
- Please enter a valid email.
244
+ {t('Please enter a valid email.')}
243
245
  </p>
244
246
  )}
245
247
  </div>
@@ -259,21 +261,23 @@ export default function InquiryModal({
259
261
  color: '#2B2C46',
260
262
  }}
261
263
  >
262
- Machine
264
+ {settings.support.prefilterFieldName}
263
265
  </p>
264
266
  <Tooltip
265
267
  title={
266
- 'Please select a pre-filter before search request to refine and yield accurate results.'
268
+ t('Please select a search criteria before search request to refine and yield accurate results.')
267
269
  }
268
270
  placement="top"
269
271
  arrow={true}
270
272
  >
271
- <Icon
272
- name="info"
273
- style={{ cursor: 'pointer' }}
274
- width={12}
275
- height={12}
276
- />
273
+ <div>
274
+ <Icon
275
+ name="info"
276
+ style={{ cursor: 'pointer' }}
277
+ width={12}
278
+ height={12}
279
+ />
280
+ </div>
277
281
  </Tooltip>
278
282
  </div>
279
283
 
@@ -288,7 +292,7 @@ export default function InquiryModal({
288
292
  backgroundColor: '#fff',
289
293
  }}
290
294
  >
291
- {preFilterValues.join(', ') || 'Pre-filter is not selected'}
295
+ {preFilterValues.join(', ') || t('Search criteria is not selected')}
292
296
  </div>
293
297
  </div>
294
298
  )}
@@ -303,7 +307,7 @@ export default function InquiryModal({
303
307
  color: '#2B2C46',
304
308
  }}
305
309
  >
306
- <p>Additional information</p>
310
+ <p>{t('Additional information')}</p>
307
311
  <p>{`${information.length}/150`}</p>
308
312
  </div>
309
313
  <TextareaAutosize
@@ -337,7 +341,7 @@ export default function InquiryModal({
337
341
  }}
338
342
  onClick={() => setIsInquiryModalOpen(false)}
339
343
  >
340
- Cancel
344
+ {t('Cancel')}
341
345
  </button>
342
346
  <button
343
347
  style={{
@@ -357,7 +361,7 @@ export default function InquiryModal({
357
361
  disabled={!emailValid}
358
362
  onClick={handleInquiry}
359
363
  >
360
- Send
364
+ {t('Send')}
361
365
  </button>
362
366
  </div>
363
367
  </div>
@@ -1,7 +1,6 @@
1
- import React, { useEffect, useMemo, useState } from 'react';
2
- import { Button, Collapse, Grid, Typography, Tooltip } from '@material-ui/core';
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import { Button, Grid, Typography, Tooltip } from '@material-ui/core';
3
3
  import CloseOutlinedIcon from '@material-ui/icons/CloseOutlined';
4
- import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
5
4
  import { Icon } from '@nyris/nyris-react-components';
6
5
  import NoImage from '../common/assets/images/no-image.svg';
7
6
  import { useMediaQuery } from 'react-responsive';
@@ -9,7 +8,6 @@ import { ImagePreviewCarousel } from './carousel/ImagePreviewCarousel';
9
8
  import { AppState } from 'types';
10
9
  import { useAppSelector } from 'Store/Store';
11
10
  import { prepareImageList } from '../helpers/CommonHelper';
12
- import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
13
11
  import { useTranslation } from 'react-i18next';
14
12
  import ProductAttribute from './ProductAttribute';
15
13
  import CadenasWebViewer from './CadenasWebViewer';
@@ -56,6 +54,9 @@ function ProductDetailView(props: Props) {
56
54
  >();
57
55
  const { t } = useTranslation();
58
56
  const classes = useStyles(props?.show3dView);
57
+ const modal = useRef<any>(null);
58
+ const extraDetailPropertyLength = isMobile ? 15 : 30;
59
+ const extraDetailValueLength = isMobile ? 35 : 60;
59
60
 
60
61
  useEffect(() => {
61
62
  if (dataItem) {
@@ -92,17 +93,10 @@ function ProductDetailView(props: Props) {
92
93
 
93
94
  setDataImageCarouSel(valueKey);
94
95
  };
95
- const productDetails = useMemo(() => {
96
- const details = get(dataItem, settings.productDetails);
97
- try {
98
- return details.join(', ');
99
- } catch (e) {
100
- return details;
101
- }
102
- }, [dataItem, settings.productDetails]);
103
96
 
104
97
  return (
105
98
  <div
99
+ ref={modal}
106
100
  className="box-modal-default"
107
101
  style={{
108
102
  margin: isMobile ? 0 : '',
@@ -591,8 +585,8 @@ function ProductDetailView(props: Props) {
591
585
  </div>
592
586
  )}
593
587
  </div>
594
-
595
- {productDetails && (
588
+
589
+ {settings.productDetailsAttribute?.length ? (
596
590
  <div className="w-100">
597
591
  <Button
598
592
  className="w-100 button-hover"
@@ -607,34 +601,98 @@ function ProductDetailView(props: Props) {
607
601
  paddingRight: '15px',
608
602
  textTransform: 'initial',
609
603
  }}
610
- onClick={() => setCollapseDescription(e => !e)}
604
+ onClick={(e) => {
605
+ setCollapseDescription(prev => !prev);
606
+ if (modal && modal.current) {
607
+ setTimeout(() => {
608
+ const top = (settings.productDetailsAttribute?.length || 0) * 30 + 20;
609
+ modal.current.parentElement.scrollTo({ top });
610
+ });
611
+ }
612
+ }}
611
613
  >
612
614
  {t('View details')}
613
- {collapseDescription ? (
614
- <KeyboardArrowUpIcon
615
- htmlColor={settings.theme?.secondaryColor}
616
- />
617
- ) : (
618
- <KeyboardArrowDownIcon
619
- htmlColor={settings.theme?.secondaryColor}
620
- />
621
- )}
615
+ <span
616
+ style={{
617
+ fontSize: 20,
618
+ }}
619
+ >
620
+ {collapseDescription ? '—' : '+'}
621
+ </span>
622
622
  </Button>
623
- <Collapse in={collapseDescription}>
624
- <Typography
623
+ {collapseDescription ? (
624
+ <div
625
625
  style={{
626
- fontSize: 14,
627
- padding: 5,
628
- paddingLeft: 15,
629
- paddingRight: 15,
630
- color: '#2b2c46',
626
+ background: '#E9E9EC',
627
+ borderRadius: 2,
628
+ display: 'flex',
629
+ flexDirection: 'column',
630
+ gap: 6,
631
+ padding: '6px 15px 10px',
631
632
  }}
632
633
  >
633
- {productDetails}
634
- </Typography>
635
- </Collapse>
634
+ {settings.productDetailsAttribute.map((detail) =>
635
+ get(dataItem, detail.value)?.length
636
+ ? (
637
+ <div
638
+ style={{
639
+ height: 14,
640
+ display: 'flex',
641
+ flexDirection: 'row',
642
+ alignItems: 'center'
643
+ }}
644
+ >
645
+ <Tooltip
646
+ title={detail.propertyName}
647
+ placement="top"
648
+ arrow={true}
649
+ disableHoverListener={detail.propertyName.length < extraDetailPropertyLength}
650
+ >
651
+ <span
652
+ style={{
653
+ fontFamily: 'Source Sans 3',
654
+ fontSize: 12,
655
+ fontWeight: 600,
656
+ marginRight: 8,
657
+ height: 14,
658
+ }}
659
+ >
660
+ {detail.propertyName.length < extraDetailPropertyLength
661
+ ? detail.propertyName
662
+ : detail.propertyName.substring(0, extraDetailPropertyLength).concat('...')
663
+ }
664
+ </span>
665
+ </Tooltip>
666
+ <Tooltip
667
+ title={get(dataItem, detail.value)}
668
+ placement="top"
669
+ arrow={true}
670
+ disableHoverListener={get(dataItem, detail.value)?.length <= extraDetailValueLength}
671
+ >
672
+ <Typography
673
+ style={{
674
+ fontFamily: 'Source Sans 3',
675
+ fontSize: 12,
676
+ fontWeight: 400,
677
+ height: 14,
678
+ }}
679
+ >
680
+ {get(dataItem, detail.value).length <= extraDetailValueLength
681
+ ? get(dataItem, detail.value)
682
+ : get(dataItem, detail.value).substring(0, extraDetailValueLength).concat('...')
683
+ }
684
+ </Typography>
685
+ </Tooltip>
686
+ </div>
687
+ )
688
+ : (
689
+ ''
690
+ )
691
+ )}
692
+ </div>
693
+ ) : ('')}
636
694
  </div>
637
- )}
695
+ ) : ('')}
638
696
  </Grid>
639
697
  </Grid>
640
698
  </div>
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
 
4
4
  import { Icon, makeFileHandler } from '@nyris/nyris-react-components';
5
+ import { useTranslation } from 'react-i18next';
5
6
 
6
7
  function UploadDisclaimer({
7
8
  onClose,
@@ -13,8 +14,7 @@ function UploadDisclaimer({
13
14
  isMobile: boolean;
14
15
  }) {
15
16
  const [dontShowAgain, setDontShowAgain] = useState(false);
16
- const isCadSearch = window.settings.cadSearch;
17
-
17
+ const { t } = useTranslation();
18
18
  return (
19
19
  <>
20
20
  {createPortal(
@@ -22,7 +22,9 @@ function UploadDisclaimer({
22
22
  <div className="bg-white w-80">
23
23
  <div className="p-4">
24
24
  <div className="flex justify-between items-center">
25
- <div className="font-bold text-xl">Replace Current Data?</div>
25
+ <div className="font-bold text-xl">
26
+ {t('Replace Current Data?')}
27
+ </div>
26
28
  <Icon
27
29
  name="close"
28
30
  className="cursor-pointer"
@@ -32,8 +34,9 @@ function UploadDisclaimer({
32
34
  />
33
35
  </div>
34
36
  <p className="text-sm mt-4">
35
- Uploading a new image will overwrite your current search
36
- parameters, text, and results. Are you sure you want to proceed?
37
+ {t(
38
+ `Uploading a new image will overwrite your current search parameters, text, and results. Are you sure you want to proceed?`,
39
+ )}
37
40
  </p>
38
41
  <div className="mt-4 gap-x-2 flex">
39
42
  <input
@@ -43,7 +46,7 @@ function UploadDisclaimer({
43
46
  setDontShowAgain(e.target.checked);
44
47
  }}
45
48
  />
46
- Don't show this again
49
+ {t(`Don't show this again`)}
47
50
  </div>
48
51
  </div>
49
52
  <div className="flex">
@@ -51,7 +54,7 @@ function UploadDisclaimer({
51
54
  className="w-1/2 h-16 p-4 text-start text-sm text-white bg-[#2B2C46]"
52
55
  onClick={() => onClose()}
53
56
  >
54
- Cancel
57
+ {t(`Cancel`)}
55
58
  </button>
56
59
  <label
57
60
  className="w-1/2 h-16 p-4 text-start text-sm text-white bg-[#E31B5D] cursor-pointer"
@@ -62,15 +65,15 @@ function UploadDisclaimer({
62
65
  }
63
66
  }}
64
67
  >
65
- Continue
68
+ {t(`Continue`)}
66
69
  </label>
67
70
  <input
68
71
  type="file"
69
72
  name="take-picture"
70
73
  id="nyris__upload-photo"
71
- accept={`${
72
- isCadSearch ? '.stp,.step,.stl,.obj,.glb,.gltf,' : ''
73
- }image/jpeg,image/png,image/webp`}
74
+ accept={
75
+ '.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,image/jpeg,image/png,image/webp'
76
+ }
74
77
  onChange={makeFileHandler(file =>
75
78
  onContinue({ file, dontShowAgain }),
76
79
  )}
@@ -257,11 +257,9 @@ function CameraCustom(props: Props) {
257
257
  handlerFindImage(file);
258
258
  }
259
259
  }}
260
- accept={`${
261
- isCadSearch
262
- ? '.stp,.step,.stl,.obj,.glb,.gltf,'
263
- : ''
264
- }image/jpeg,image/png,image/webp`}
260
+ accept={
261
+ '.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,image/jpeg,image/png,image/webp'
262
+ }
265
263
  onClick={event => {
266
264
  // @ts-ignore
267
265
  event.target.value = '';
@@ -322,8 +322,10 @@ const SearchBox = (props: any) => {
322
322
  <div className="wrap-box-input-mobile d-flex">
323
323
  <input
324
324
  accept={`${
325
- isCadSearch ? '.stp,.step,.stl,.obj,.glb,.gltf,' : ''
326
- }image/*`}
325
+ isCadSearch
326
+ ? '.stp,.step,.stl,.obj,.glb,.gltf,.heic,.heif,image/*'
327
+ : ''
328
+ }`}
327
329
  id="icon-button-file"
328
330
  type="file"
329
331
  style={{ display: 'none' }}
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { getCroppedCanvas } from 'helpers/getCroppedCanvas';
3
3
  import { useMediaQuery } from 'react-responsive';
4
+ import { useTranslation } from 'react-i18next';
4
5
 
5
6
  function RfqBanner({
6
7
  requestImage,
@@ -16,7 +17,7 @@ function RfqBanner({
16
17
  selectedRegion: any;
17
18
  }) {
18
19
  const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
19
-
20
+ const { t } = useTranslation();
20
21
  return (
21
22
  <div
22
23
  style={{
@@ -66,8 +67,8 @@ function RfqBanner({
66
67
  }}
67
68
  >
68
69
  {isMobile
69
- ? 'No matches found?'
70
- : 'No matches found for your request?'}
70
+ ? `${t('No matches found')}?`
71
+ : `${t('No matches found for your request')}?`}
71
72
  </div>
72
73
  <div
73
74
  style={{
@@ -78,7 +79,7 @@ function RfqBanner({
78
79
  fontWeight: 'normal',
79
80
  }}
80
81
  >
81
- Get personalised help from our team of product experts.
82
+ {t('Get personalised help from our team of product experts.')}
82
83
  </div>
83
84
  </div>
84
85
  <button