@nyris/nyris-webapp 0.3.35 → 0.3.36

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.a2657ad49c132fb9c82629d37be15547.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.ff44260e.chunk.js +3 -0
  8. package/build/static/js/2.ff44260e.chunk.js.map +1 -0
  9. package/build/static/js/main.0b3b11fc.chunk.js +3 -0
  10. package/build/static/js/main.0b3b11fc.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 +5 -4
  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.ff44260e.chunk.js.LICENSE.txt} +0 -0
  57. /package/build/static/js/{main.f579fa9f.chunk.js.LICENSE.txt → main.0b3b11fc.chunk.js.LICENSE.txt} +0 -0
@@ -1,12 +1,12 @@
1
1
  import { Box, Button, Tooltip, Typography } from '@material-ui/core';
2
- import React, { useEffect, useState } from 'react';
2
+ import React, { useEffect, useMemo, useState } from 'react';
3
3
  import CloseIcon from '@material-ui/icons/Close';
4
4
  import IconSearch from 'common/assets/icons/icon_search.svg';
5
5
  import { getFilters, searchFilters } from 'services/filter';
6
6
  import { useAppDispatch, useAppSelector } from 'Store/Store';
7
- import { setUpdateKeyFilterDesktop } from 'Store/search/Search';
7
+ import { setPreFilter } from 'Store/search/Search';
8
8
  import { useMediaQuery } from 'react-responsive';
9
- import { isEmpty } from 'lodash';
9
+ import { isEmpty, pickBy } from 'lodash';
10
10
  import { Skeleton } from '@material-ui/lab';
11
11
  import { truncateString } from 'helpers/truncateString';
12
12
 
@@ -14,21 +14,35 @@ interface Props {
14
14
  handleClose?: any;
15
15
  // onChangeKeyFilter?: any;
16
16
  }
17
-
17
+ const maxFilter = 10;
18
18
  function PreFilterComponent(props: Props) {
19
19
  const { handleClose } = props;
20
20
  const dispatch = useAppDispatch();
21
21
  const stateGlobal = useAppSelector(state => state);
22
22
  const {
23
23
  settings,
24
- search: { keyFilter: keyFilterState },
24
+ search: { preFilter: keyFilterState },
25
25
  } = stateGlobal;
26
26
  const [resultFilter, setResultFilter] = useState<any>([]);
27
- const [keyFilter, setKeyFilter] = useState<string>(keyFilterState || '');
27
+ const [keyFilter, setKeyFilter] = useState<Record<string, boolean>>(
28
+ keyFilterState || {},
29
+ );
30
+
28
31
  const [isLoading, setLoading] = useState<boolean>(false);
29
32
  const [columns, setColumns] = useState<number>(0);
30
33
  const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
31
34
 
35
+ const selectedFilter = useMemo(
36
+ () =>
37
+ Object.keys(keyFilter).reduce((count, key) => {
38
+ if (keyFilter[key] === true) {
39
+ return count + 1;
40
+ }
41
+ return count;
42
+ }, 0),
43
+ [keyFilter],
44
+ );
45
+
32
46
  const getDataFilterDesktop = async () => {
33
47
  setLoading(true);
34
48
  const dataResultFilter = getFilters(1000, settings)
@@ -73,7 +87,6 @@ function PreFilterComponent(props: Props) {
73
87
  settings,
74
88
  )
75
89
  .then(res => {
76
- // console.log("res", res);
77
90
  if (res.length > 0) {
78
91
  setResultFilter({ [res[0][0].toLocaleUpperCase()]: res });
79
92
  if (res.length <= 20) setColumns(1);
@@ -92,7 +105,7 @@ function PreFilterComponent(props: Props) {
92
105
  };
93
106
 
94
107
  const onHandlerSubmitData = () => {
95
- dispatch(setUpdateKeyFilterDesktop(keyFilter));
108
+ dispatch(setPreFilter(pickBy(keyFilter, value => !!value)));
96
109
  handleClose();
97
110
  };
98
111
 
@@ -119,7 +132,7 @@ function PreFilterComponent(props: Props) {
119
132
  color: '#000',
120
133
  fontSize: '24px',
121
134
  fontWeight: 700,
122
- paddingLeft: isMobile ? '0px' : '14px',
135
+ paddingLeft: '14px',
123
136
  marginBottom: isMobile ? '0px' : '-8px',
124
137
  marginTop: isMobile ? '0px' : '24px',
125
138
  }}
@@ -133,7 +146,6 @@ function PreFilterComponent(props: Props) {
133
146
  </div>
134
147
  <Box
135
148
  className="box-top"
136
- style={isMobile ? { padding: 0, marginTop: '16px' } : undefined}
137
149
  display={'flex'}
138
150
  justifyContent={'space-between'}
139
151
  alignItems={'center'}
@@ -144,34 +156,21 @@ function PreFilterComponent(props: Props) {
144
156
  justifyItems={'center'}
145
157
  style={isMobile ? { width: '100%' } : undefined}
146
158
  >
147
- {(!keyFilter || isMobile) && (
148
- <Box
149
- className="icon-search"
150
- style={{ marginRight: 11 }}
151
- display={'flex'}
152
- justifyContent={'center'}
153
- alignItems={'center'}
154
- >
155
- <img
156
- style={{ maxWidth: 'fit-content' }}
157
- src={IconSearch}
158
- alt=""
159
- width={18}
160
- height={18}
161
- />
162
- </Box>
163
- )}
164
-
165
- {keyFilter && !isMobile && (
166
- <Box display={'flex'} className="box-keyFilter">
167
- <Typography className="keyFilter max-line-1">
168
- {keyFilter}
169
- </Typography>
170
- <Button style={{ padding: 0 }} onClick={() => setKeyFilter('')}>
171
- <CloseIcon style={{ fontSize: 12, color: '#2B2C46' }} />
172
- </Button>
173
- </Box>
174
- )}
159
+ <Box
160
+ className="icon-search"
161
+ style={{ marginRight: 11 }}
162
+ display={'flex'}
163
+ justifyContent={'center'}
164
+ alignItems={'center'}
165
+ >
166
+ <img
167
+ style={{ maxWidth: 'fit-content' }}
168
+ src={IconSearch}
169
+ alt=""
170
+ width={18}
171
+ height={18}
172
+ />
173
+ </Box>
175
174
 
176
175
  <input
177
176
  className="input-search-filter"
@@ -183,19 +182,59 @@ function PreFilterComponent(props: Props) {
183
182
  </Box>
184
183
  </Box>
185
184
 
186
- {keyFilter && isMobile && (
187
- <Box style={{ margin: '10px 16px' }}>
185
+ {!isEmpty(keyFilter) && selectedFilter > 0 && (
186
+ <Box
187
+ style={{
188
+ margin: '10px 16px 10px 16px',
189
+ display: 'flex',
190
+ justifyContent: 'space-between',
191
+ }}
192
+ >
188
193
  <Box
189
- display={'flex'}
190
- className="box-keyFilter"
191
- style={{ display: 'inline-flex' }}
194
+ style={{
195
+ display: 'flex',
196
+ flexWrap: 'wrap',
197
+ rowGap: '8px',
198
+ columnGap: '8px',
199
+ alignItems: 'baseline',
200
+ fontSize: '12px',
201
+ marginBottom: '4px',
202
+ }}
192
203
  >
193
- <Typography className="keyFilter max-line-1">
194
- {keyFilter}
195
- </Typography>
196
- <Button style={{ padding: 0 }} onClick={() => setKeyFilter('')}>
197
- <CloseIcon style={{ fontSize: 12, color: '#2B2C46' }} />
198
- </Button>
204
+ {Object.keys(keyFilter).map((key, index) => {
205
+ if (!keyFilter[key]) return <></>;
206
+ return (
207
+ <Box
208
+ key={index}
209
+ className="box-keyFilter"
210
+ style={{ display: 'flex', height: 'fit-content' }}
211
+ >
212
+ <Typography className="keyFilter">{key}</Typography>
213
+ <Button
214
+ style={{ padding: 0 }}
215
+ onClick={() => setKeyFilter({ ...keyFilter, [key]: false })}
216
+ >
217
+ <CloseIcon style={{ fontSize: 12, color: '#2B2C46' }} />
218
+ </Button>
219
+ </Box>
220
+ );
221
+ })}
222
+ <p
223
+ style={{ fontWeight: 'bold', color: '#000' }}
224
+ >{`${selectedFilter}/${maxFilter}`}</p>
225
+ <Box
226
+ style={{
227
+ color: '#E31B5D',
228
+ fontSize: '12px',
229
+ cursor: 'pointer',
230
+ marginLeft: '12px',
231
+ }}
232
+ onClick={() => {
233
+ setKeyFilter({});
234
+ }}
235
+ >
236
+ Clear all
237
+ </Box>
199
238
  </Box>
200
239
  </Box>
201
240
  )}
@@ -204,7 +243,10 @@ function PreFilterComponent(props: Props) {
204
243
  height={'100%'}
205
244
  style={
206
245
  isMobile
207
- ? { columnCount: 1, marginBottom: keyFilter ? '50px' : '0px' }
246
+ ? {
247
+ columnCount: 1,
248
+ marginBottom: keyFilter ? '50px' : '0px',
249
+ }
208
250
  : columns <= 4
209
251
  ? { columnCount: columns, height: '100%', paddingBottom: 20 }
210
252
  : { columnCount: 4, paddingBottom: 20 }
@@ -248,12 +290,22 @@ function PreFilterComponent(props: Props) {
248
290
  minHeight: '20px',
249
291
  color: '#2B2C46',
250
292
  width: '100%',
293
+ maxWidth: 'fit-content',
251
294
  overflow: 'hidden',
252
295
  textOverflow: 'ellipsis',
253
296
  whiteSpace: 'nowrap',
297
+ backgroundColor: keyFilter[item] ? '#E9E9EC' : '',
298
+ borderRadius: 8,
299
+ paddingLeft: '8px',
300
+ paddingRight: '8px',
254
301
  }}
255
302
  onClick={() => {
256
- setKeyFilter(item);
303
+ if (selectedFilter < maxFilter) {
304
+ setKeyFilter({
305
+ ...keyFilter,
306
+ [item]: !keyFilter[item],
307
+ });
308
+ }
257
309
  }}
258
310
  >
259
311
  {truncateString(item, !isMobile ? 35 : 35)}
@@ -297,10 +349,13 @@ function PreFilterComponent(props: Props) {
297
349
  className="button-left"
298
350
  style={{
299
351
  width: '50%',
352
+ height: '64px',
300
353
  backgroundColor: '#000000',
301
354
  color: '#fff',
302
355
  borderRadius: 0,
303
356
  justifyContent: 'flex-start',
357
+ textTransform: 'none',
358
+ paddingLeft: '16px',
304
359
  }}
305
360
  onClick={() => handleClose()}
306
361
  >
@@ -314,6 +369,8 @@ function PreFilterComponent(props: Props) {
314
369
  color: '#fff',
315
370
  borderRadius: 0,
316
371
  justifyContent: 'flex-start',
372
+ textTransform: 'none',
373
+ paddingLeft: '16px',
317
374
  }}
318
375
  onClick={() => onHandlerSubmitData()}
319
376
  >
@@ -217,7 +217,7 @@ function ItemResult(props: Props) {
217
217
  <span style={{ marginRight: 3 }}>
218
218
  {settings.itemIdLabel || 'SKU'}:
219
219
  </span>
220
- {truncateString(sku, 20)}
220
+ {truncateString(sku, isMobile ? 17 : 20)}
221
221
  </Typography>
222
222
  </Tooltip>
223
223
 
@@ -0,0 +1,262 @@
1
+ import DefaultModal from 'components/modal/DefaultModal';
2
+ import React, { useEffect, useState } from 'react';
3
+ import CloseIcon from '@material-ui/icons/Close';
4
+ import { getCroppedCanvas } from 'helpers/getCroppedCanvas';
5
+ import emailjs from '@emailjs/browser';
6
+ import { ToastHelper } from 'helpers/ToastHelper';
7
+ import { isUndefined } from 'lodash';
8
+ import { TextareaAutosize } from '@material-ui/core';
9
+ import toast from 'react-hot-toast';
10
+ import { ReactComponent as ErrorIcon } from 'common/assets/icons/error.svg';
11
+ interface Props {
12
+ requestImage: any;
13
+ selectedRegion: any;
14
+ setIsRfqModalOpen: any;
15
+ isRfqModalOpen?: any;
16
+ setRfqStatus: any;
17
+ }
18
+ // eslint-disable-next-line
19
+ const emailRegex = /.+\@.+\..+$/;
20
+
21
+ const getErrorMessage = (error: any) => {
22
+ switch (error.status) {
23
+ case 400:
24
+ return 'Your email could not be sent, please try again or send an email to support@nyris.io';
25
+ case 421:
26
+ case 450:
27
+ case 451:
28
+ case 452:
29
+ return "Email delivery failed. Rest assured, we're continuously attempting to send it for you. Alternatively, you can forward the email to support@nyris.io";
30
+ default:
31
+ return 'Your email could not be sent, please try again or send an email to support@nyris.io';
32
+ }
33
+ };
34
+
35
+ export default function RfqModal({
36
+ requestImage,
37
+ selectedRegion,
38
+ setIsRfqModalOpen,
39
+ isRfqModalOpen,
40
+ setRfqStatus,
41
+ }: Props) {
42
+ const [email, setEmail] = useState('');
43
+ const [emailValid, setEmailValid] = useState<boolean | undefined>(undefined);
44
+
45
+ const [information, setInformation] = useState('');
46
+ useEffect(() => emailjs.init('SMGihPnuEGcYLm0V4'), []);
47
+ useEffect(() => {
48
+ if (email)
49
+ emailRegex.test(email) ? setEmailValid(true) : setEmailValid(false);
50
+ }, [email]);
51
+
52
+ const handleRfq = async (e: { preventDefault: () => void }) => {
53
+ e.preventDefault();
54
+ const { canvas }: any = requestImage;
55
+ const croppedImage = getCroppedCanvas(canvas, selectedRegion);
56
+ const serviceId = 'service_zfsxshi';
57
+ const templateId = 'template_jlgc9le';
58
+ setIsRfqModalOpen(false);
59
+ try {
60
+ setRfqStatus('loading');
61
+ await emailjs.send(serviceId, templateId, {
62
+ email_id: email.trim(),
63
+ information_text: information,
64
+ request_image: croppedImage?.toDataURL(),
65
+ });
66
+ setRfqStatus('sent');
67
+ ToastHelper.success('Request sent successfully');
68
+ } catch (error) {
69
+ setRfqStatus('inactive');
70
+
71
+ toast(
72
+ t => {
73
+ return (
74
+ <div
75
+ style={{
76
+ display: 'flex',
77
+ flexDirection: 'column',
78
+ fontSize: '14px',
79
+ width: '294px',
80
+ }}
81
+ >
82
+ <span style={{ fontWeight: 'bold' }}>Email not sent</span>
83
+ <span>{getErrorMessage(error)}</span>
84
+ <a
85
+ href={`mailto:support@nyris.io?subject=Request for quotation&body=${information}`}
86
+ style={{
87
+ padding: '8px 16px 8px 16px',
88
+ border: '1px solid #000',
89
+ marginTop: '16px',
90
+ backgroundColor: 'transparent',
91
+ color: '#000',
92
+ cursor: 'pointer',
93
+ width: 'fit-content',
94
+ }}
95
+ >
96
+ support@nyris.io
97
+ </a>
98
+ </div>
99
+ );
100
+ },
101
+ {
102
+ duration: 5000,
103
+ style: {
104
+ background: '#FFE5EF',
105
+ color: '#000000',
106
+ maxWidth: '400px',
107
+ },
108
+ icon: (
109
+ <div style={{ minWidth: '20px', minHeight: '20px' }}>
110
+ <ErrorIcon />
111
+ </div>
112
+ ),
113
+ },
114
+ );
115
+ }
116
+ setIsRfqModalOpen(false);
117
+ };
118
+
119
+ return (
120
+ <DefaultModal
121
+ openModal={isRfqModalOpen}
122
+ handleClose={(e: any) => {
123
+ setIsRfqModalOpen(false);
124
+ }}
125
+ >
126
+ <div
127
+ style={{
128
+ display: 'flex',
129
+ width: '378px',
130
+ flexDirection: 'column',
131
+ backgroundColor: '#fff',
132
+ }}
133
+ >
134
+ <div
135
+ style={{
136
+ padding: '16px',
137
+ display: 'flex',
138
+ flexDirection: 'column',
139
+ }}
140
+ >
141
+ <CloseIcon
142
+ style={{
143
+ fontSize: 16,
144
+ color: 'black',
145
+ alignSelf: 'flex-end',
146
+ cursor: 'pointer',
147
+ }}
148
+ onClick={() => setIsRfqModalOpen(false)}
149
+ />
150
+ <p
151
+ style={{
152
+ color: '#2B2C46',
153
+ fontSize: '20px',
154
+ fontWeight: 'bold',
155
+ }}
156
+ >
157
+ Submit your image for quotation
158
+ </p>
159
+ </div>
160
+ <div
161
+ style={{
162
+ padding: '16px',
163
+ backgroundColor: '#F3F3F5',
164
+ display: 'flex',
165
+ justifyContent: 'center',
166
+ }}
167
+ >
168
+ <img
169
+ src={getCroppedCanvas(
170
+ requestImage?.canvas,
171
+ selectedRegion,
172
+ )?.toDataURL()}
173
+ alt="request_image"
174
+ style={{ maxHeight: '200px' }}
175
+ />
176
+ </div>
177
+ <div
178
+ style={{
179
+ padding: '0px 16px 16px 16px',
180
+ backgroundColor: '#F3F3F5',
181
+ display: 'flex',
182
+ flexDirection: 'column',
183
+ rowGap: '16px',
184
+ }}
185
+ >
186
+ <div>
187
+ <p style={{ fontSize: '12px', color: '#2B2C46' }}>
188
+ Your email (required)
189
+ </p>
190
+ <input
191
+ value={email}
192
+ onChange={e => setEmail(e.currentTarget.value.trim())}
193
+ style={{
194
+ width: '100%',
195
+ border: 'none',
196
+ height: '32px',
197
+ padding: '8px 16px 8px 16px',
198
+ }}
199
+ />
200
+ {!emailValid && !isUndefined(emailValid) && (
201
+ <p style={{ color: 'red', fontSize: '12px', paddingTop: '8px' }}>
202
+ Please enter a valid email.
203
+ </p>
204
+ )}
205
+ </div>
206
+ <div>
207
+ <p style={{ fontSize: '12px', color: '#2B2C46' }}>
208
+ Additional information
209
+ </p>
210
+ <TextareaAutosize
211
+ value={information}
212
+ onChange={e => setInformation(e.currentTarget.value)}
213
+ style={{
214
+ width: '100%',
215
+ border: 'none',
216
+ maxWidth: '346px',
217
+ padding: '8px 16px 8px 16px',
218
+ }}
219
+ />
220
+ </div>
221
+ </div>
222
+ <div style={{ display: 'flex' }}>
223
+ <button
224
+ style={{
225
+ height: '66px',
226
+ display: 'flex',
227
+ alignItems: 'center',
228
+ width: '50%',
229
+ backgroundColor: '#4B4B4A',
230
+ color: 'white',
231
+ fontSize: '14px',
232
+ paddingLeft: '16px',
233
+ border: 'none',
234
+ cursor: 'pointer',
235
+ }}
236
+ onClick={() => setIsRfqModalOpen(false)}
237
+ >
238
+ Cancel
239
+ </button>
240
+ <button
241
+ style={{
242
+ height: '66px',
243
+ display: 'flex',
244
+ alignItems: 'center',
245
+ width: '50%',
246
+ backgroundColor: emailValid ? '#4DBE51' : '#E9E9EC',
247
+ color: emailValid ? '#fff' : '#AAABB5',
248
+ fontSize: '14px',
249
+ paddingLeft: '16px',
250
+ border: 'none',
251
+ cursor: emailValid ? 'pointer' : 'normal',
252
+ }}
253
+ disabled={!emailValid}
254
+ onClick={handleRfq}
255
+ >
256
+ Send
257
+ </button>
258
+ </div>
259
+ </div>
260
+ </DefaultModal>
261
+ );
262
+ }
@@ -10,4 +10,14 @@ export class ToastHelper {
10
10
  },
11
11
  });
12
12
  }
13
+
14
+ static error(msg: string) {
15
+ toast.error(msg, {
16
+ duration: 3000,
17
+ style: {
18
+ background: '#1E1F31',
19
+ color: '#fff',
20
+ },
21
+ });
22
+ }
13
23
  }
@@ -0,0 +1,26 @@
1
+ import {
2
+ RectCoords,
3
+ getElementSize,
4
+ getRectAspectRatio,
5
+ getThumbSizeArea,
6
+ elementToCanvas,
7
+ } from '@nyris/nyris-api';
8
+
9
+ export const getCroppedCanvas = (
10
+ canvas: HTMLCanvasElement | HTMLImageElement | HTMLVideoElement,
11
+ cropRect?: RectCoords,
12
+ ) => {
13
+ let crop = cropRect || {
14
+ x1: 0,
15
+ x2: 1,
16
+ y1: 0,
17
+ y2: 1,
18
+ };
19
+ if (!canvas) return null;
20
+
21
+ const originalSize = getElementSize(canvas);
22
+ const aspectRatio = getRectAspectRatio(crop, originalSize);
23
+ let scaledSize = getThumbSizeArea(600, 600, aspectRatio);
24
+ let resizedCroppedCanvas = elementToCanvas(canvas, scaledSize, crop);
25
+ return resizedCroppedCanvas;
26
+ };
@@ -0,0 +1,37 @@
1
+ import { useMemo } from 'react';
2
+
3
+ const useFilteredRegions = (regions: any, imageSelection: any) => {
4
+ const filteredRegions = useMemo(
5
+ () =>
6
+ regions.map(
7
+ (region: {
8
+ normalizedRect: { x1: any; x2: any; y1: any; y2: any };
9
+ }) => {
10
+ if (
11
+ region.normalizedRect?.x1 === imageSelection?.x1 &&
12
+ region.normalizedRect?.x2 === imageSelection?.x2 &&
13
+ region.normalizedRect?.y1 === imageSelection?.y1 &&
14
+ region.normalizedRect?.y2 === imageSelection?.y2
15
+ ) {
16
+ return { ...region, show: false };
17
+ }
18
+ if (
19
+ imageSelection?.x1 === 0 &&
20
+ imageSelection?.x2 === 1 &&
21
+ imageSelection?.y1 === 0 &&
22
+ imageSelection?.y2 === 1
23
+ ) {
24
+ return { ...region, show: false };
25
+ }
26
+
27
+ return { ...region, show: true };
28
+ },
29
+ ),
30
+
31
+ [regions, imageSelection],
32
+ );
33
+
34
+ return filteredRegions;
35
+ };
36
+
37
+ export default useFilteredRegions;
package/src/index.css CHANGED
@@ -581,10 +581,6 @@ h6 {
581
581
  margin: 22px auto 8px;
582
582
  }
583
583
 
584
- p {
585
- margin-bottom: 16px;
586
- }
587
-
588
584
  p a {
589
585
  text-decoration: underline;
590
586
  }
@@ -3,12 +3,9 @@ import React, { useState } from 'react';
3
3
  import './common.scss';
4
4
  import { cadExtensions } from '@nyris/nyris-api';
5
5
  import algoliasearch from 'algoliasearch/lite';
6
- import IconSupport from 'common/assets/icons/support3.svg';
7
6
  import DragDropFile from 'components/DragDropFile';
8
7
  import CustomSearchBox from 'components/input/inputSearch';
9
8
  import { connectInfiniteHits } from 'react-instantsearch-dom';
10
- import { useMediaQuery } from 'react-responsive';
11
- import { Link } from 'react-router-dom';
12
9
  import { useAppSelector } from 'Store/Store';
13
10
  import { AlgoliaSettings } from '../../types';
14
11
 
@@ -18,7 +15,6 @@ function AppMD() {
18
15
  const { apiKey, appId, indexName } = settings.algolia as AlgoliaSettings;
19
16
  const searchClient = algoliasearch(appId, apiKey);
20
17
  searchClient.initIndex(indexName);
21
- const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
22
18
 
23
19
  const acceptTypes = ['image/*']
24
20
  .concat(settings.cadSearch ? cadExtensions : [])
@@ -36,13 +32,6 @@ function AppMD() {
36
32
 
37
33
  return (
38
34
  <Box className={`box-content-main ${isLoading ? 'loading' : ''}`}>
39
- {isMobile && (
40
- <Box className="btn-open-support">
41
- <Link to={'/support'} style={{ color: '#3E36DC' }}>
42
- <img src={IconSupport} alt="" width={16} height={16} />
43
- </Link>
44
- </Box>
45
- )}
46
35
  <Box className="box-content_top">
47
36
  <Box className="fw-700 text-f32 text-dark2">
48
37
  <h1>{settings.headerText}</h1>
@@ -21,6 +21,7 @@ function AppMobile(): JSX.Element {
21
21
  justifyContent: 'center',
22
22
  alignItems: 'center',
23
23
  width: '100%',
24
+ height: '100%',
24
25
  }}
25
26
  >
26
27
  <div className="take-photo">