@nyris/nyris-webapp 0.3.46 → 0.3.48
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.
- package/build/asset-manifest.json +16 -12
- package/build/index.html +1 -1
- package/build/js/settings.example.js +84 -13
- package/build/{precache-manifest.003c83b03ba38cefb9af2060ababe0b4.js → precache-manifest.87ecf17e376539dad2c663829130bfdc.js} +26 -10
- package/build/service-worker.js +1 -1
- package/build/static/css/main.24b5a712.chunk.css +2 -0
- package/build/static/css/main.24b5a712.chunk.css.map +1 -0
- package/build/static/js/2.f9395632.chunk.js +3 -0
- package/build/static/js/2.f9395632.chunk.js.map +1 -0
- package/build/static/js/main.e2a2eb38.chunk.js +3 -0
- package/build/static/js/main.e2a2eb38.chunk.js.map +1 -0
- package/build/static/media/add.ba46a4bf.svg +4 -0
- package/build/static/media/arrow_left.fd9d4390.svg +3 -0
- package/build/static/media/arrow_right.c6fdab0b.svg +3 -0
- package/build/static/media/minus.3fce6c0a.svg +3 -0
- package/package.json +4 -4
- package/public/js/settings.example.js +84 -13
- package/src/Store/Store.ts +1 -0
- package/src/Store/search/Search.ts +36 -0
- package/src/Store/search/search.initialState.ts +1 -0
- package/src/Store/search/types.ts +1 -0
- package/src/common/assets/icons/add.svg +4 -0
- package/src/common/assets/icons/minus.svg +3 -0
- package/src/components/HeaderMobile.tsx +33 -12
- package/src/components/ImagePreviewMobile.tsx +52 -134
- package/src/components/Inquiry/InquiryBanner.tsx +6 -3
- package/src/components/Layout.tsx +19 -1
- package/src/components/MobilePostFilter.tsx +14 -5
- package/src/components/PanelResult/PostFilter.tsx +314 -0
- package/src/components/PanelResult/{index.tsx → PostFilterAlgolia.tsx} +44 -15
- package/src/components/PanelResult/expandable-panel.tsx +20 -14
- package/src/components/ProductAttribute.tsx +38 -34
- package/src/components/ProductDetailView.tsx +37 -22
- package/src/components/ProductList/index.tsx +0 -3
- package/src/components/ProductList/useProductList.ts +6 -3
- package/src/components/SelectedPostFilter.tsx +103 -0
- package/src/components/SidePanel.tsx +40 -22
- package/src/components/appMobile.scss +7 -0
- package/src/components/common.scss +4 -0
- package/src/components/current-refinements/getCurrentRefinement.ts +10 -18
- package/src/components/drawer/cameraCustom.tsx +14 -64
- package/src/components/icon-label/icon-label.tsx +23 -18
- package/src/components/input/inputSearch.tsx +2 -2
- package/src/components/pre-filter/index.tsx +16 -10
- package/src/components/results/ItemResult.tsx +33 -22
- package/src/hooks/useFilter.ts +92 -0
- package/src/hooks/useFilteredResult.ts +29 -0
- package/src/index.css +2 -1
- package/src/page/landingPage/AppMD.tsx +1 -5
- package/src/page/landingPage/common.scss +10 -3
- package/src/page/result/index.tsx +37 -29
- package/src/services/image.ts +0 -5
- package/src/translations.ts +16 -0
- package/src/types.ts +1 -5
- package/build/static/css/main.5b89f23f.chunk.css +0 -2
- package/build/static/css/main.5b89f23f.chunk.css.map +0 -1
- package/build/static/js/2.f3840c8e.chunk.js +0 -3
- package/build/static/js/2.f3840c8e.chunk.js.map +0 -1
- package/build/static/js/main.d68884f6.chunk.js +0 -3
- package/build/static/js/main.d68884f6.chunk.js.map +0 -1
- /package/build/static/js/{2.f3840c8e.chunk.js.LICENSE.txt → 2.f9395632.chunk.js.LICENSE.txt} +0 -0
- /package/build/static/js/{main.d68884f6.chunk.js.LICENSE.txt → main.e2a2eb38.chunk.js.LICENSE.txt} +0 -0
|
@@ -20,7 +20,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
20
20
|
import ProductAttribute from './ProductAttribute';
|
|
21
21
|
import CadenasWebViewer from './CadenasWebViewer';
|
|
22
22
|
import { makeStyles } from '@material-ui/core/styles';
|
|
23
|
-
import { get } from 'lodash';
|
|
23
|
+
import { get, isUndefined } from 'lodash';
|
|
24
24
|
|
|
25
25
|
const useStyles = makeStyles(theme => ({
|
|
26
26
|
buttonStyle3D: {
|
|
@@ -321,25 +321,31 @@ function ProductDetailView(props: Props) {
|
|
|
321
321
|
{sku}
|
|
322
322
|
</Typography>
|
|
323
323
|
|
|
324
|
-
{settings.warehouseVariant &&
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
>
|
|
331
|
-
<span
|
|
324
|
+
{settings.warehouseVariant &&
|
|
325
|
+
!isUndefined(
|
|
326
|
+
get(dataItem, settings.field.warehouseStockValue),
|
|
327
|
+
) && (
|
|
328
|
+
<Typography
|
|
329
|
+
className="text-f12 max-line-1 fw-400"
|
|
332
330
|
style={{
|
|
333
|
-
color:
|
|
334
|
-
? '#00C070'
|
|
335
|
-
: '#c54545',
|
|
336
|
-
fontWeight: 600,
|
|
331
|
+
color: '#2B2C46',
|
|
337
332
|
}}
|
|
338
333
|
>
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
334
|
+
<span
|
|
335
|
+
style={{
|
|
336
|
+
color: get(
|
|
337
|
+
dataItem,
|
|
338
|
+
settings.field.warehouseStockValue,
|
|
339
|
+
)
|
|
340
|
+
? '#00C070'
|
|
341
|
+
: '#c54545',
|
|
342
|
+
fontWeight: 600,
|
|
343
|
+
}}
|
|
344
|
+
>
|
|
345
|
+
{get(dataItem, settings.field.warehouseStockValue) || 0}
|
|
346
|
+
</span>
|
|
347
|
+
</Typography>
|
|
348
|
+
)}
|
|
343
349
|
</Box>
|
|
344
350
|
)}
|
|
345
351
|
|
|
@@ -403,19 +409,28 @@ function ProductDetailView(props: Props) {
|
|
|
403
409
|
<>
|
|
404
410
|
{settings.field.warehouseNumber && (
|
|
405
411
|
<ProductAttribute
|
|
406
|
-
title={
|
|
412
|
+
title={
|
|
413
|
+
get(dataItem, settings.field.warehouseNumber) ||
|
|
414
|
+
settings.field.warehouseNumber
|
|
415
|
+
}
|
|
407
416
|
value={
|
|
408
|
-
dataItem
|
|
417
|
+
get(dataItem, settings.field.warehouseNumberValue) ||
|
|
418
|
+
'N/A'
|
|
409
419
|
}
|
|
410
420
|
width={{ xs: '49%', md: 'fit-content' }}
|
|
411
421
|
/>
|
|
412
422
|
)}
|
|
413
423
|
{settings.field.warehouseShelfNumber && (
|
|
414
424
|
<ProductAttribute
|
|
415
|
-
title={
|
|
425
|
+
title={
|
|
426
|
+
get(dataItem, settings.field.warehouseShelfNumber) ||
|
|
427
|
+
settings.field.warehouseShelfNumber
|
|
428
|
+
}
|
|
416
429
|
value={
|
|
417
|
-
|
|
418
|
-
|
|
430
|
+
get(
|
|
431
|
+
dataItem,
|
|
432
|
+
settings.field.warehouseShelfNumberValue,
|
|
433
|
+
) || 'N/A'
|
|
419
434
|
}
|
|
420
435
|
width={{ xs: '49%', md: 'fit-content' }}
|
|
421
436
|
/>
|
|
@@ -13,7 +13,6 @@ interface Props {
|
|
|
13
13
|
getUrlToCanvasFile: any;
|
|
14
14
|
setLoading?: any;
|
|
15
15
|
sendFeedBackAction: any;
|
|
16
|
-
moreInfoText: any;
|
|
17
16
|
requestImage?: any;
|
|
18
17
|
searchQuery?: string;
|
|
19
18
|
}
|
|
@@ -22,7 +21,6 @@ function ProductListComponent({
|
|
|
22
21
|
allSearchResults,
|
|
23
22
|
getUrlToCanvasFile,
|
|
24
23
|
sendFeedBackAction,
|
|
25
|
-
moreInfoText,
|
|
26
24
|
searchQuery,
|
|
27
25
|
requestImage,
|
|
28
26
|
isSearchStalled,
|
|
@@ -79,7 +77,6 @@ function ProductListComponent({
|
|
|
79
77
|
handlerCloseGroup(hitItem, index)
|
|
80
78
|
}
|
|
81
79
|
isGroupItem={settings.showGroup ? hit?.isGroup : false}
|
|
82
|
-
moreInfoText={moreInfoText}
|
|
83
80
|
main_image_link={
|
|
84
81
|
hit['image(main_similarity)'] || hit['main_image_link']
|
|
85
82
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useAppSelector } from 'Store/Store';
|
|
2
|
+
import { useFilteredResult } from 'hooks/useFilteredResult';
|
|
2
3
|
import { groupBy, uniqueId } from 'lodash';
|
|
3
4
|
import { useEffect, useMemo, useState } from 'react';
|
|
4
5
|
|
|
@@ -91,14 +92,16 @@ export const useProductList = ({ allSearchResults, isSearchStalled }: any) => {
|
|
|
91
92
|
}
|
|
92
93
|
}, [isSearchStalled]);
|
|
93
94
|
|
|
95
|
+
const filteredResult = useFilteredResult(results);
|
|
96
|
+
|
|
94
97
|
const productList = useMemo(() => {
|
|
95
|
-
return
|
|
98
|
+
return filteredResult?.map((item: any) => {
|
|
96
99
|
return {
|
|
97
100
|
...item,
|
|
98
|
-
main_image_link: item.image || item.images ? item.images[0] : '',
|
|
101
|
+
main_image_link: item.image || (item.images ? item.images[0] : ''),
|
|
99
102
|
};
|
|
100
103
|
});
|
|
101
|
-
}, [
|
|
104
|
+
}, [filteredResult]);
|
|
102
105
|
|
|
103
106
|
return {
|
|
104
107
|
productList: algolia?.enabled ? itemShowDefault : productList || [],
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { ReactComponent as IconClose } from 'common/assets/icons/close.svg';
|
|
4
|
+
import { atom } from 'jotai';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
import { useAppDispatch, useAppSelector } from 'Store/Store';
|
|
7
|
+
import { useFilter } from 'hooks/useFilter';
|
|
8
|
+
import { get } from 'lodash';
|
|
9
|
+
import { clearPostFilter, setPostFilter } from 'Store/search/Search';
|
|
10
|
+
import { Box } from '@material-ui/core';
|
|
11
|
+
|
|
12
|
+
export type CurrentRefinementsProps = {
|
|
13
|
+
className?: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type CurrentRefinement = {
|
|
17
|
+
category?: string;
|
|
18
|
+
label: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const refinementCountAtom = atom(0);
|
|
22
|
+
|
|
23
|
+
export function SelectedPostFilter({ className }: CurrentRefinementsProps) {
|
|
24
|
+
const stateGlobal = useAppSelector(state => state);
|
|
25
|
+
const dispatch = useAppDispatch();
|
|
26
|
+
const {
|
|
27
|
+
search: { postFilter, results },
|
|
28
|
+
} = stateGlobal;
|
|
29
|
+
const filter = useFilter(results);
|
|
30
|
+
|
|
31
|
+
const selectedFilters = useMemo(() => {
|
|
32
|
+
const selectedFilters: any[] = [];
|
|
33
|
+
Object.keys(filter).forEach(key => {
|
|
34
|
+
const values = filter[key];
|
|
35
|
+
values.forEach((data: { value: string }) => {
|
|
36
|
+
if (get(postFilter, `${key}.${data.value}`)) {
|
|
37
|
+
selectedFilters.push({ key, ...data });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
return selectedFilters;
|
|
42
|
+
}, [filter, postFilter]);
|
|
43
|
+
|
|
44
|
+
if (!selectedFilters.length) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Box className="wrap-box-refinements">
|
|
50
|
+
<div style={{ display: 'flex', flexFlow: 'wrap', columnGap: '8px' }}>
|
|
51
|
+
{selectedFilters.map(filter => {
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
key={filter.value}
|
|
55
|
+
style={{
|
|
56
|
+
display: 'flex',
|
|
57
|
+
alignItems: 'center',
|
|
58
|
+
columnGap: '12px',
|
|
59
|
+
fontSize: '12px',
|
|
60
|
+
padding: '4px 8px 4px 8px',
|
|
61
|
+
backgroundColor: '#E9E9EC',
|
|
62
|
+
borderRadius: '18px',
|
|
63
|
+
width: 'fit-content',
|
|
64
|
+
}}
|
|
65
|
+
>
|
|
66
|
+
<p>
|
|
67
|
+
{filter.value} ({filter.count})
|
|
68
|
+
</p>
|
|
69
|
+
<div
|
|
70
|
+
style={{
|
|
71
|
+
padding: '2px',
|
|
72
|
+
display: 'flex',
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
justifyContent: 'center',
|
|
75
|
+
cursor: 'pointer',
|
|
76
|
+
}}
|
|
77
|
+
onClick={() => {
|
|
78
|
+
dispatch(
|
|
79
|
+
setPostFilter({
|
|
80
|
+
[filter.key]: filter.value,
|
|
81
|
+
}),
|
|
82
|
+
);
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
<IconClose width={12} height={12} />
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
})}
|
|
90
|
+
<div
|
|
91
|
+
key="clear"
|
|
92
|
+
className={classNames('flex items-center')}
|
|
93
|
+
style={{ padding: '4px', cursor: 'pointer' }}
|
|
94
|
+
onClick={() => dispatch(clearPostFilter())}
|
|
95
|
+
>
|
|
96
|
+
<div className="text-f12" style={{ color: '#E31B5D' }}>
|
|
97
|
+
Clear all
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</Box>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
@@ -2,11 +2,14 @@ import { Box, Button, Typography } from '@material-ui/core';
|
|
|
2
2
|
import { RectCoords } from '@nyris/nyris-api';
|
|
3
3
|
import { Preview } from '@nyris/nyris-react-components';
|
|
4
4
|
import React, { useState } from 'react';
|
|
5
|
-
import
|
|
5
|
+
import PostFilterPanel from './PanelResult/PostFilter';
|
|
6
|
+
import PostFilterPanelAlgolia from './PanelResult/PostFilterAlgolia';
|
|
7
|
+
|
|
6
8
|
import { useTranslation } from 'react-i18next';
|
|
7
9
|
import { useAppSelector } from 'Store/Store';
|
|
8
|
-
import KeyboardArrowRightOutlinedIcon from '
|
|
9
|
-
import KeyboardArrowLeftOutlinedIcon from '
|
|
10
|
+
import { ReactComponent as KeyboardArrowRightOutlinedIcon } from 'common/assets/icons/arrow_right.svg';
|
|
11
|
+
import { ReactComponent as KeyboardArrowLeftOutlinedIcon } from 'common/assets/icons/arrow_left.svg';
|
|
12
|
+
|
|
10
13
|
import { DEFAULT_REGION } from '../constants';
|
|
11
14
|
import { ReactComponent as IconInfo } from 'common/assets/icons/info-tooltip.svg';
|
|
12
15
|
|
|
@@ -32,7 +35,7 @@ function SidePanel({
|
|
|
32
35
|
}) {
|
|
33
36
|
const { t } = useTranslation();
|
|
34
37
|
const [toggleColLeft, setToggleColLeft] = useState<boolean>(false);
|
|
35
|
-
const stateGlobal = useAppSelector(
|
|
38
|
+
const stateGlobal = useAppSelector(state => state);
|
|
36
39
|
const { search, settings } = stateGlobal;
|
|
37
40
|
|
|
38
41
|
const { requestImage } = search;
|
|
@@ -49,7 +52,7 @@ function SidePanel({
|
|
|
49
52
|
<Box
|
|
50
53
|
className="box-toggle-coloumn"
|
|
51
54
|
style={{
|
|
52
|
-
right:
|
|
55
|
+
right: '0px',
|
|
53
56
|
}}
|
|
54
57
|
>
|
|
55
58
|
<Button
|
|
@@ -82,28 +85,35 @@ function SidePanel({
|
|
|
82
85
|
>
|
|
83
86
|
<div
|
|
84
87
|
style={{
|
|
88
|
+
display: 'flex',
|
|
89
|
+
justifyContent: 'center',
|
|
85
90
|
backgroundColor: '#F3F3F5',
|
|
86
91
|
width: '100%',
|
|
87
92
|
paddingTop: '16px',
|
|
88
93
|
paddingBottom: '16px',
|
|
89
94
|
}}
|
|
90
95
|
>
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
debouncedOnImageSelectionChange(r);
|
|
96
|
+
<div
|
|
97
|
+
style={{
|
|
98
|
+
width: '288px',
|
|
99
|
+
height: 'fit-content',
|
|
96
100
|
}}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
>
|
|
102
|
+
<Preview
|
|
103
|
+
key={requestImage?.id}
|
|
104
|
+
onSelectionChange={(r: RectCoords) => {
|
|
105
|
+
setImageSelection(r);
|
|
106
|
+
debouncedOnImageSelectionChange(r);
|
|
107
|
+
}}
|
|
108
|
+
image={requestImage?.canvas}
|
|
109
|
+
selection={imageSelection || DEFAULT_REGION}
|
|
110
|
+
regions={filteredRegions}
|
|
111
|
+
dotColor={'#FBD914'}
|
|
112
|
+
minCropWidth={60}
|
|
113
|
+
minCropHeight={60}
|
|
114
|
+
rounded={true}
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
107
117
|
</div>
|
|
108
118
|
</Box>
|
|
109
119
|
</Box>
|
|
@@ -135,8 +145,16 @@ function SidePanel({
|
|
|
135
145
|
)}
|
|
136
146
|
|
|
137
147
|
{showPostFilter && (
|
|
138
|
-
<Box
|
|
139
|
-
|
|
148
|
+
<Box
|
|
149
|
+
className="col-left__bottom"
|
|
150
|
+
style={{
|
|
151
|
+
marginTop: requestImage ? '16px' : '48px',
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
{settings.algolia.enabled && (
|
|
155
|
+
<PostFilterPanelAlgolia disjunctiveFacets={disjunctiveFacets} />
|
|
156
|
+
)}
|
|
157
|
+
{!settings.algolia.enabled && <PostFilterPanel />}
|
|
140
158
|
</Box>
|
|
141
159
|
)}
|
|
142
160
|
</Box>
|
|
@@ -514,6 +514,12 @@
|
|
|
514
514
|
|
|
515
515
|
video {
|
|
516
516
|
overflow: hidden;
|
|
517
|
+
height: 100%;
|
|
518
|
+
width: 100%;
|
|
519
|
+
object-fit: cover;
|
|
520
|
+
min-width: 100%;
|
|
521
|
+
min-height: 100%;
|
|
522
|
+
|
|
517
523
|
}
|
|
518
524
|
}
|
|
519
525
|
|
|
@@ -706,6 +712,7 @@
|
|
|
706
712
|
border-radius: 100%;
|
|
707
713
|
padding: 30px;
|
|
708
714
|
.outer {
|
|
715
|
+
display: block;
|
|
709
716
|
border-radius: 100%;
|
|
710
717
|
padding: 3px;
|
|
711
718
|
background: linear-gradient(180deg, #AAABB5 0%, #FFFFFF 100%);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CurrentRefinement } from
|
|
1
|
+
import type { CurrentRefinement } from './current-refinements';
|
|
2
2
|
|
|
3
3
|
function getRefinementConfig(r: any, refinement: any) {
|
|
4
4
|
const refinementOptions = r.attribute;
|
|
@@ -10,7 +10,7 @@ function getRefinementConfig(r: any, refinement: any) {
|
|
|
10
10
|
|
|
11
11
|
export function getCurrentRefinement(
|
|
12
12
|
refinement: any,
|
|
13
|
-
config: any
|
|
13
|
+
config: any,
|
|
14
14
|
): CurrentRefinement[] {
|
|
15
15
|
let refinementConfig: any;
|
|
16
16
|
config.forEach((r: any) => {
|
|
@@ -18,20 +18,12 @@ export function getCurrentRefinement(
|
|
|
18
18
|
refinementConfig = r;
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
value: item.value,
|
|
30
|
-
})) || []
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
default: {
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
}
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
refinement?.items?.map((item: any) => ({
|
|
24
|
+
category: refinementConfig?.header,
|
|
25
|
+
label: item.label,
|
|
26
|
+
value: item.value,
|
|
27
|
+
})) || []
|
|
28
|
+
);
|
|
37
29
|
}
|
|
@@ -6,7 +6,6 @@ import { RectCoords } from '@nyris/nyris-api';
|
|
|
6
6
|
import ReverseCamera from 'common/assets/icons/reverse_camera.svg';
|
|
7
7
|
import { isEmpty } from 'lodash';
|
|
8
8
|
import React, { useCallback, useRef, useState } from 'react';
|
|
9
|
-
import { useDropzone } from 'react-dropzone';
|
|
10
9
|
import { useHistory } from 'react-router-dom';
|
|
11
10
|
import Webcam from 'react-webcam';
|
|
12
11
|
import { createImage, find, findRegions } from 'services/image';
|
|
@@ -43,9 +42,9 @@ function CameraCustom(props: Props) {
|
|
|
43
42
|
|
|
44
43
|
const videoConstraints = {
|
|
45
44
|
width: 1080,
|
|
46
|
-
|
|
47
|
-
aspectRatio: 1.33333333333,
|
|
45
|
+
aspectRatio: 1.11111,
|
|
48
46
|
};
|
|
47
|
+
|
|
49
48
|
const handleClick = useCallback(() => {
|
|
50
49
|
setFacingMode(prevState =>
|
|
51
50
|
prevState === FACING_MODE_USER
|
|
@@ -63,7 +62,6 @@ function CameraCustom(props: Props) {
|
|
|
63
62
|
let region: RectCoords | undefined;
|
|
64
63
|
let imageConvert = await createImage(image);
|
|
65
64
|
dispatch(setRequestImage(imageConvert));
|
|
66
|
-
dispatch(setImageSearchInput(image));
|
|
67
65
|
dispatch(onToggleModalItemDetail(false));
|
|
68
66
|
handlerCloseModal();
|
|
69
67
|
|
|
@@ -114,60 +112,6 @@ function CameraCustom(props: Props) {
|
|
|
114
112
|
onToggleModal();
|
|
115
113
|
};
|
|
116
114
|
|
|
117
|
-
const { getInputProps } = useDropzone({
|
|
118
|
-
onDrop: async (fs: File[]) => {
|
|
119
|
-
let payload: any;
|
|
120
|
-
let filters: any[] = [];
|
|
121
|
-
let region: RectCoords | undefined;
|
|
122
|
-
dispatch(updateStatusLoading(true));
|
|
123
|
-
dispatch(setImageSearchInput(URL.createObjectURL(fs[0])));
|
|
124
|
-
let image = await createImage(fs[0]);
|
|
125
|
-
dispatch(setRequestImage(image));
|
|
126
|
-
if (settings.regions) {
|
|
127
|
-
let res = await findRegions(image, settings);
|
|
128
|
-
dispatch(setRegions(res.regions));
|
|
129
|
-
region = res.selectedRegion;
|
|
130
|
-
dispatch(setSelectedRegion(region));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const preFilterValues = [
|
|
134
|
-
{
|
|
135
|
-
key: settings.visualSearchFilterKey,
|
|
136
|
-
values: Object.keys(preFilter) as string[],
|
|
137
|
-
},
|
|
138
|
-
];
|
|
139
|
-
return find({
|
|
140
|
-
image,
|
|
141
|
-
settings,
|
|
142
|
-
filters: !isEmpty(preFilter) ? preFilterValues : undefined,
|
|
143
|
-
region,
|
|
144
|
-
})
|
|
145
|
-
.then((res: any) => {
|
|
146
|
-
res?.results.map((item: any) => {
|
|
147
|
-
filters.push({
|
|
148
|
-
sku: item.sku,
|
|
149
|
-
score: item.score,
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
payload = {
|
|
153
|
-
...res,
|
|
154
|
-
filters,
|
|
155
|
-
};
|
|
156
|
-
dispatch(setSearchResults(payload));
|
|
157
|
-
setTimeout(() => {
|
|
158
|
-
dispatch(updateStatusLoading(false));
|
|
159
|
-
handlerCloseModal();
|
|
160
|
-
history.push('/result');
|
|
161
|
-
}, 500);
|
|
162
|
-
})
|
|
163
|
-
.catch((e: any) => {
|
|
164
|
-
console.log('err camera_custom', e);
|
|
165
|
-
dispatch(updateStatusLoading(false));
|
|
166
|
-
handlerCloseModal();
|
|
167
|
-
});
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
115
|
return (
|
|
172
116
|
<Box className="box-camera-custom">
|
|
173
117
|
<Drawer
|
|
@@ -222,6 +166,7 @@ function CameraCustom(props: Props) {
|
|
|
222
166
|
onClick={() => {
|
|
223
167
|
const imageSrc = getScreenshot();
|
|
224
168
|
handlerFindImage(imageSrc);
|
|
169
|
+
dispatch(setImageSearchInput(imageSrc));
|
|
225
170
|
}}
|
|
226
171
|
className="btn-capture-camera"
|
|
227
172
|
>
|
|
@@ -285,12 +230,17 @@ function CameraCustom(props: Props) {
|
|
|
285
230
|
id="icon-button-file"
|
|
286
231
|
type="file"
|
|
287
232
|
style={{ display: 'none' }}
|
|
288
|
-
{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
233
|
+
onChange={(fs: any) => {
|
|
234
|
+
const file = fs.target?.files[0];
|
|
235
|
+
if (!file) return;
|
|
236
|
+
dispatch(setImageSearchInput(URL.createObjectURL(file)));
|
|
237
|
+
handlerFindImage(file);
|
|
238
|
+
}}
|
|
239
|
+
accept="image/jpeg,image/png,image/webp"
|
|
240
|
+
onClick={event => {
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
event.target.value = '';
|
|
243
|
+
}}
|
|
294
244
|
/>
|
|
295
245
|
<label htmlFor="icon-button-file">
|
|
296
246
|
<IconButton
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React, { useEffect, useState } from
|
|
2
|
-
import RemoveIcon from
|
|
3
|
-
import AddIcon from
|
|
4
|
-
import { Typography } from "@material-ui/core";
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { ReactComponent as RemoveIcon } from 'common/assets/icons/minus.svg';
|
|
3
|
+
import { ReactComponent as AddIcon } from 'common/assets/icons/add.svg';
|
|
5
4
|
|
|
6
|
-
export type LabelPosition =
|
|
5
|
+
export type LabelPosition = 'bottom' | 'left' | 'right' | 'top';
|
|
7
6
|
|
|
8
7
|
export type IconLabelProps = {
|
|
9
8
|
icon?: any;
|
|
@@ -16,11 +15,11 @@ export type IconLabelProps = {
|
|
|
16
15
|
export default function IconLabel({
|
|
17
16
|
icon,
|
|
18
17
|
label,
|
|
19
|
-
labelPosition =
|
|
20
|
-
className =
|
|
21
|
-
classNameLabel =
|
|
18
|
+
labelPosition = 'bottom',
|
|
19
|
+
className = 'gap-1',
|
|
20
|
+
classNameLabel = '',
|
|
22
21
|
}: IconLabelProps) {
|
|
23
|
-
const [tagIcon, setTagIcon] = useState<string>(
|
|
22
|
+
const [tagIcon, setTagIcon] = useState<string>('');
|
|
24
23
|
// let classNamePosition: string;
|
|
25
24
|
// switch (labelPosition) {
|
|
26
25
|
// case "top":
|
|
@@ -42,25 +41,31 @@ export default function IconLabel({
|
|
|
42
41
|
}, [icon]);
|
|
43
42
|
|
|
44
43
|
return (
|
|
45
|
-
<div
|
|
44
|
+
<div
|
|
45
|
+
style={{
|
|
46
|
+
display: 'flex',
|
|
47
|
+
alignItems: 'center',
|
|
48
|
+
gap: '8px',
|
|
49
|
+
paddingRight: '2px',
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
46
52
|
{label && (
|
|
47
53
|
<div className={classNameLabel}>
|
|
48
|
-
<
|
|
54
|
+
<p
|
|
49
55
|
style={{
|
|
50
|
-
textTransform: "none",
|
|
51
56
|
fontSize: 12,
|
|
52
|
-
color:
|
|
53
|
-
fontWeight:
|
|
57
|
+
color: '#2B2C46',
|
|
58
|
+
fontWeight: 500,
|
|
54
59
|
}}
|
|
55
60
|
>
|
|
56
61
|
{label}
|
|
57
|
-
</
|
|
62
|
+
</p>
|
|
58
63
|
</div>
|
|
59
64
|
)}
|
|
60
|
-
{tagIcon ===
|
|
61
|
-
<RemoveIcon
|
|
65
|
+
{tagIcon === 'remove' ? (
|
|
66
|
+
<RemoveIcon width={16} height={16} />
|
|
62
67
|
) : (
|
|
63
|
-
<AddIcon
|
|
68
|
+
<AddIcon width={16} height={16} />
|
|
64
69
|
)}
|
|
65
70
|
</div>
|
|
66
71
|
);
|
|
@@ -212,7 +212,7 @@ const SearchBox = (props: any) => {
|
|
|
212
212
|
return (
|
|
213
213
|
<div className="wrap-input-search-field">
|
|
214
214
|
<div className="box-input-search d-flex">
|
|
215
|
-
<
|
|
215
|
+
<div className="input-wrapper">
|
|
216
216
|
<Box className="box-inp">
|
|
217
217
|
<Tooltip
|
|
218
218
|
title={
|
|
@@ -426,7 +426,7 @@ const SearchBox = (props: any) => {
|
|
|
426
426
|
</Button>
|
|
427
427
|
</Box>
|
|
428
428
|
)}
|
|
429
|
-
</
|
|
429
|
+
</div>
|
|
430
430
|
</div>
|
|
431
431
|
{settings.preFilterOption && (
|
|
432
432
|
<DefaultModal
|