@nyris/nyris-webapp 0.3.58 → 0.3.59
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 +15 -16
- package/build/index.html +1 -1
- package/build/js/settings.example.js +1 -1
- package/build/static/css/main.cb6e2cfd.css +4 -0
- package/build/static/css/main.cb6e2cfd.css.map +1 -0
- package/build/static/js/main.a1e24447.js +3 -0
- package/build/static/js/{main.8728b671.js.LICENSE.txt → main.a1e24447.js.LICENSE.txt} +55 -0
- package/build/static/js/main.a1e24447.js.map +1 -0
- package/build/static/media/camera_simple.bff4194954bbb5f4bc33bd99014a93e8.svg +3 -0
- package/build/static/media/collpase.50dae91fff891c46b10dfc281344d0ef.svg +6 -0
- package/build/static/media/crop.0676ebbbdc1375ed67e32bba890ce941.svg +3 -0
- package/build/static/media/{download.8007f7c72e2080a9ffa96fa63d480dcf.svg → download.a8452bc23334e9f8e53fe1225742d216.svg} +1 -1
- package/build/static/media/gallery.15d1f3308921480a8c9d96d9a77c9966.svg +3 -0
- package/build/static/media/{logout.b544fcd2969edf431a1e998333119834.svg → logout.bab56bd407f25eb34d6eff401a436ce1.svg} +1 -1
- package/build/static/media/next-arrow.b13263d05d107ceb5e99bc4fabb41279.svg +3 -0
- package/build/static/media/plus.329672cb2feb55345490589e91481b88.svg +3 -0
- package/package.json +8 -5
- package/public/index.html +0 -3
- package/public/js/settings.example.js +1 -1
- package/src/Router.tsx +2 -2
- package/src/Store/Store.ts +2 -0
- package/src/Store/requestStore.ts +70 -0
- package/src/Store/resultStore.ts +25 -0
- package/src/Store/search/Search.ts +2 -33
- package/src/Store/search/search.initialState.ts +1 -4
- package/src/Store/search/types.ts +0 -5
- package/src/common/assets/icons/arrow_enter.svg +3 -0
- package/src/common/assets/icons/camera_simple.svg +3 -0
- package/src/common/assets/icons/collpase.svg +6 -0
- package/src/common/assets/icons/crop.svg +3 -0
- package/src/common/assets/icons/download.svg +1 -1
- package/src/common/assets/icons/gallery.svg +3 -0
- package/src/common/assets/icons/logout.svg +1 -1
- package/src/common/assets/icons/next-arrow.svg +3 -0
- package/src/common/assets/icons/plus.svg +3 -0
- package/src/components/CadenasWebViewer.tsx +1 -1
- package/src/components/DragDropFile.tsx +17 -77
- package/src/components/Experience-visual-search/ExperienceVisualSearch.tsx +47 -71
- package/src/components/Feedback.tsx +23 -9
- package/src/components/GoBackButton.tsx +15 -18
- package/src/components/HeaderMobile.tsx +342 -246
- package/src/components/ImageCaptureHelpModal.tsx +63 -65
- package/src/components/ImagePreview.tsx +564 -0
- package/src/components/Inquiry/InquiryBanner.tsx +1 -1
- package/src/components/Inquiry/InquiryModal.tsx +4 -7
- package/src/components/Layout.tsx +9 -18
- package/src/components/MobileLayout.tsx +51 -0
- package/src/components/MobilePostFilter.tsx +9 -3
- package/src/components/PanelResult/PostFilterAlgolia.tsx +4 -32
- package/src/components/PanelResult/expandable-panel.tsx +3 -16
- package/src/components/PanelResult/virtual-state-results.ts +17 -22
- package/src/components/SidePanel.tsx +7 -97
- package/src/components/UploadDisclaimer.tsx +85 -0
- package/src/components/appMobile.scss +2 -2
- package/src/components/common.scss +57 -27
- package/src/components/drawer/cameraCustom.tsx +389 -231
- package/src/components/icon-label/icon-label.tsx +1 -1
- package/src/components/input/inputSearch.tsx +197 -338
- package/src/components/pre-filter/index.tsx +70 -71
- package/src/components/results/ItemResult.tsx +33 -16
- package/src/components/rfq/RfqBanner.tsx +1 -4
- package/src/components/rfq/RfqModal.tsx +10 -10
- package/src/hooks/useFilteredRegions.ts +1 -1
- package/src/hooks/useImageSearch.ts +189 -0
- package/src/hooks/useSearchOrRedirect.ts +84 -0
- package/src/index.css +4 -0
- package/src/page/landingPage/Home.tsx +49 -0
- package/src/page/landingPage/{AppMD.tsx → HomeDesktop.tsx} +7 -34
- package/src/page/landingPage/{AppMobile.tsx → HomeMobile.tsx} +8 -37
- package/src/page/landingPage/common.scss +9 -1
- package/src/page/result/index.tsx +118 -232
- package/src/services/Feedback.ts +4 -5
- package/src/services/image.ts +19 -0
- package/src/types.ts +9 -8
- package/src/utils.ts +44 -0
- package/tailwind.config.js +54 -0
- package/build/static/css/main.67965609.css +0 -2
- package/build/static/css/main.67965609.css.map +0 -1
- package/build/static/js/main.8728b671.js +0 -3
- package/build/static/js/main.8728b671.js.map +0 -1
- package/build/static/media/arrow_down.f417689ce292978a8292a7f00407fdd5.svg +0 -3
- package/build/static/media/arrow_left.73d03a534eaf9b99ab196e0fb67da602.svg +0 -3
- package/build/static/media/arrow_right.59a4594a3a1657037537dbae1eee0251.svg +0 -3
- package/build/static/media/arrow_up.85dbe70bc51ec32c8894a06499330f14.svg +0 -3
- package/build/static/media/home.9ffb65a9c0be8fc5a502ba05cf5f719c.svg +0 -3
- package/build/static/media/icon_camera_mobile.6772053c4dfef487255649d2a05cc9d4.svg +0 -3
- package/build/static/media/reverse_camera.cee0200b151941cc83c182167a85d667.svg +0 -5
- package/src/App.tsx +0 -18
- package/src/components/AppMobile.tsx +0 -117
- package/src/components/FooterMobile.tsx +0 -230
- package/src/components/ImagePreviewMobile.tsx +0 -237
- /package/build/static/media/{add.2b72cedb98c4c89c954266d2356c166c.svg → add-rounded.2b72cedb98c4c89c954266d2356c166c.svg} +0 -0
- /package/src/common/assets/icons/{add.svg → add-rounded.svg} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useState, memo, useEffect, useRef } from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
3
|
import CloseOutlinedIcon from '@material-ui/icons/CloseOutlined';
|
|
4
4
|
import './ExperienceVisualSearch.scss';
|
|
@@ -7,28 +7,21 @@ import { useAppDispatch, useAppSelector } from '../../Store/Store';
|
|
|
7
7
|
import { ReactComponent as IconSearchImage } from 'common/assets/icons/icon_search_image2.svg';
|
|
8
8
|
import {
|
|
9
9
|
loadingActionResults,
|
|
10
|
-
setImageSearchInput,
|
|
11
|
-
setRegions,
|
|
12
|
-
setRequestImage,
|
|
13
|
-
setSearchResults,
|
|
14
|
-
setSelectedRegion,
|
|
15
10
|
updateStatusLoading,
|
|
16
|
-
setFirstSearchResults,
|
|
17
|
-
setFirstSearchImage,
|
|
18
|
-
setFirstSearchPrefilters,
|
|
19
|
-
setFirstSearchThumbSearchInput
|
|
20
11
|
} from '../../Store/search/Search';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { isEmpty } from 'lodash';
|
|
12
|
+
import { useImageSearch } from 'hooks/useImageSearch';
|
|
13
|
+
import { useHistory } from 'react-router-dom';
|
|
24
14
|
|
|
25
15
|
function ExperienceVisualSearch() {
|
|
26
16
|
const dispatch = useAppDispatch();
|
|
27
|
-
const {
|
|
17
|
+
const { settings } = useAppSelector(state => state);
|
|
28
18
|
const [showModal, setShowModal] = useState(false);
|
|
29
|
-
const [images, setImages] = useState<string[]>([])
|
|
19
|
+
const [images, setImages] = useState<string[]>([]);
|
|
30
20
|
const button = useRef(null);
|
|
31
21
|
let interval = useRef<NodeJS.Timeout | null>(null);
|
|
22
|
+
const history = useHistory();
|
|
23
|
+
|
|
24
|
+
const { singleImageSearch } = useImageSearch();
|
|
32
25
|
|
|
33
26
|
useEffect(() => {
|
|
34
27
|
if (document.body.getBoundingClientRect().width >= 776) {
|
|
@@ -40,7 +33,10 @@ function ExperienceVisualSearch() {
|
|
|
40
33
|
}, 3000);
|
|
41
34
|
} else if (interval?.current) {
|
|
42
35
|
clearInterval(interval?.current);
|
|
43
|
-
if (
|
|
36
|
+
if (
|
|
37
|
+
button?.current &&
|
|
38
|
+
!(button.current as HTMLElement).classList.contains('hover')
|
|
39
|
+
) {
|
|
44
40
|
(button.current as HTMLElement).classList.toggle('hover');
|
|
45
41
|
}
|
|
46
42
|
}
|
|
@@ -48,15 +44,17 @@ function ExperienceVisualSearch() {
|
|
|
48
44
|
if (interval?.current) {
|
|
49
45
|
clearInterval(interval?.current);
|
|
50
46
|
}
|
|
51
|
-
}
|
|
47
|
+
};
|
|
52
48
|
}
|
|
53
49
|
}, [showModal]);
|
|
54
50
|
|
|
55
51
|
const modalToggle = (isOpen: boolean) => {
|
|
56
52
|
setShowModal(isOpen);
|
|
57
53
|
if (isOpen) {
|
|
58
|
-
const randomImages = settings?.experienceVisualSearchImages
|
|
59
|
-
|
|
54
|
+
const randomImages = settings?.experienceVisualSearchImages?.slice(
|
|
55
|
+
0,
|
|
56
|
+
Math.min(settings?.experienceVisualSearchImages?.length, 4),
|
|
57
|
+
);
|
|
60
58
|
setImages(randomImages || []);
|
|
61
59
|
document.body.classList.add('overflow-hidden');
|
|
62
60
|
} else {
|
|
@@ -67,41 +65,13 @@ function ExperienceVisualSearch() {
|
|
|
67
65
|
const getUrlToCanvasFile = async (url: string) => {
|
|
68
66
|
dispatch(updateStatusLoading(true));
|
|
69
67
|
dispatch(loadingActionResults());
|
|
70
|
-
dispatch(setImageSearchInput(url));
|
|
71
|
-
let image = await createImage(url);
|
|
72
|
-
dispatch(setRequestImage(image));
|
|
73
|
-
|
|
74
|
-
let searchRegion: RectCoords | undefined = undefined;
|
|
75
68
|
|
|
76
|
-
|
|
77
|
-
let res = await findRegions(image, settings);
|
|
78
|
-
searchRegion = res.selectedRegion;
|
|
79
|
-
dispatch(setRegions(res.regions));
|
|
80
|
-
dispatch(setSelectedRegion(searchRegion));
|
|
81
|
-
}
|
|
82
|
-
const preFilterValues = [
|
|
83
|
-
{
|
|
84
|
-
key: settings.visualSearchFilterKey,
|
|
85
|
-
values: Object.keys(search.preFilter) as string[],
|
|
86
|
-
},
|
|
87
|
-
];
|
|
88
|
-
find({
|
|
89
|
-
image,
|
|
90
|
-
settings,
|
|
91
|
-
region: searchRegion,
|
|
92
|
-
filters: !isEmpty(search.preFilter) ? preFilterValues : undefined,
|
|
93
|
-
}).then((res: any) => {
|
|
94
|
-
dispatch(setSearchResults(res));
|
|
69
|
+
singleImageSearch({ image: url, settings }).then(() => {
|
|
95
70
|
dispatch(updateStatusLoading(false));
|
|
96
|
-
// go back
|
|
97
|
-
dispatch(setFirstSearchResults(res));
|
|
98
|
-
dispatch(setFirstSearchImage(image));
|
|
99
|
-
dispatch(setFirstSearchPrefilters(search.preFilter));
|
|
100
|
-
dispatch(setFirstSearchThumbSearchInput(url));
|
|
101
|
-
return;
|
|
102
71
|
});
|
|
72
|
+
history.push('/result');
|
|
103
73
|
};
|
|
104
|
-
|
|
74
|
+
|
|
105
75
|
return (
|
|
106
76
|
<>
|
|
107
77
|
<div
|
|
@@ -116,56 +86,62 @@ function ExperienceVisualSearch() {
|
|
|
116
86
|
createPortal(
|
|
117
87
|
<div
|
|
118
88
|
className="custom-modal"
|
|
119
|
-
onClick={
|
|
89
|
+
onClick={e => {
|
|
120
90
|
e.stopPropagation();
|
|
121
91
|
modalToggle(false);
|
|
122
92
|
}}
|
|
123
93
|
>
|
|
124
94
|
<div
|
|
125
95
|
className="custom-modal-body"
|
|
126
|
-
onClick={
|
|
96
|
+
onClick={e => {
|
|
127
97
|
e.stopPropagation();
|
|
128
98
|
}}
|
|
129
99
|
>
|
|
130
100
|
<CloseOutlinedIcon
|
|
131
101
|
style={{ fontSize: 24, color: '#55566B' }}
|
|
132
102
|
className="close-icon"
|
|
133
|
-
onClick={
|
|
103
|
+
onClick={e => {
|
|
134
104
|
e.stopPropagation();
|
|
135
105
|
modalToggle(false);
|
|
136
106
|
}}
|
|
137
107
|
/>
|
|
138
|
-
<div className="custom-modal-body-title">
|
|
108
|
+
<div className="custom-modal-body-title">
|
|
109
|
+
Experience Visual Search
|
|
110
|
+
</div>
|
|
139
111
|
<div className="custom-modal-body-subtitle">
|
|
140
112
|
Start your visual search by selecting an image below.
|
|
141
113
|
</div>
|
|
142
114
|
<div className="custom-modal-body-content experience-visual-search-images">
|
|
143
|
-
{images.map(
|
|
115
|
+
{images.map(itemImage => (
|
|
116
|
+
<div
|
|
117
|
+
className="experience-visual-search-image-container"
|
|
118
|
+
onClick={() => {
|
|
119
|
+
modalToggle(false);
|
|
120
|
+
getUrlToCanvasFile(itemImage);
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
144
123
|
<div
|
|
145
|
-
className="experience-visual-search-image
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
getUrlToCanvasFile(itemImage);
|
|
124
|
+
className="experience-visual-search-image"
|
|
125
|
+
style={{
|
|
126
|
+
backgroundImage: `url(${itemImage}?width=192&height=192)`,
|
|
149
127
|
}}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
128
|
+
/>
|
|
129
|
+
<div className="box-icon-modal">
|
|
130
|
+
<IconSearchImage
|
|
131
|
+
width={16}
|
|
132
|
+
height={16}
|
|
133
|
+
color={'#AAABB5'}
|
|
154
134
|
/>
|
|
155
|
-
<div
|
|
156
|
-
className="box-icon-modal"
|
|
157
|
-
>
|
|
158
|
-
<IconSearchImage width={16} height={16} color={'#AAABB5'} />
|
|
159
|
-
</div>
|
|
160
135
|
</div>
|
|
136
|
+
</div>
|
|
161
137
|
))}
|
|
162
138
|
</div>
|
|
163
139
|
</div>
|
|
164
140
|
</div>,
|
|
165
|
-
document.body
|
|
141
|
+
document.body,
|
|
166
142
|
)}
|
|
167
143
|
</>
|
|
168
|
-
)
|
|
144
|
+
);
|
|
169
145
|
}
|
|
170
146
|
|
|
171
|
-
export default memo(ExperienceVisualSearch);
|
|
147
|
+
export default memo(ExperienceVisualSearch);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import { ReactComponent as IconLike } from 'common/assets/icons/icon_like.svg';
|
|
3
3
|
import { ReactComponent as IconDislike } from 'common/assets/icons/icon_dislike.svg';
|
|
4
4
|
import { ReactComponent as IconClose } from 'common/assets/icons/close.svg';
|
|
@@ -10,23 +10,37 @@ function Feedback({
|
|
|
10
10
|
submitFeedback: any;
|
|
11
11
|
onFeedbackClose: any;
|
|
12
12
|
}) {
|
|
13
|
-
|
|
14
|
-
<div className="feedback-wrapper">
|
|
15
|
-
<p>Are these results useful?</p>
|
|
13
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
16
14
|
|
|
15
|
+
return (
|
|
16
|
+
<div
|
|
17
|
+
className={`feedback-wrapper`}
|
|
18
|
+
style={{
|
|
19
|
+
backgroundColor: isHovered ? '#D3D1FF' : '#e4e3ffed',
|
|
20
|
+
transition: 'background-color 0.3s ease',
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
<p className="desktop:w-[146px]">Are these results useful?</p>
|
|
17
24
|
<div
|
|
18
25
|
className="feedback-icon-wrapper"
|
|
26
|
+
onClick={() => submitFeedback(false)}
|
|
27
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
28
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
29
|
+
>
|
|
30
|
+
<IconDislike />
|
|
31
|
+
</div>
|
|
32
|
+
<div
|
|
33
|
+
className="feedback-icon-wrapper scroll-n"
|
|
19
34
|
onClick={() => submitFeedback(true)}
|
|
35
|
+
onMouseEnter={() => setIsHovered(true)}
|
|
36
|
+
onMouseLeave={() => setIsHovered(false)}
|
|
20
37
|
>
|
|
21
38
|
<IconLike />
|
|
22
39
|
</div>
|
|
23
40
|
<div
|
|
24
|
-
className="feedback-icon-wrapper"
|
|
25
|
-
onClick={() =>
|
|
41
|
+
className="feedback-icon-wrapper-close"
|
|
42
|
+
onClick={() => onFeedbackClose()}
|
|
26
43
|
>
|
|
27
|
-
<IconDislike />
|
|
28
|
-
</div>
|
|
29
|
-
<div className="feedback-icon-wrapper" onClick={() => onFeedbackClose()}>
|
|
30
44
|
<IconClose />
|
|
31
45
|
</div>
|
|
32
46
|
</div>
|
|
@@ -1,54 +1,51 @@
|
|
|
1
|
-
import React, {useCallback} from 'react';
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { useMediaQuery } from 'react-responsive';
|
|
4
4
|
import { CurrentRefinementsProvided } from 'react-instantsearch-core';
|
|
5
5
|
import {
|
|
6
|
-
setImageSearchInput,
|
|
7
6
|
setPreFilter,
|
|
8
7
|
setRequestImage,
|
|
9
8
|
setSearchResults,
|
|
10
|
-
clearPostFilter
|
|
9
|
+
clearPostFilter,
|
|
11
10
|
} from '../Store/search/Search';
|
|
12
11
|
import { connectCurrentRefinements } from 'react-instantsearch-dom';
|
|
13
12
|
import { ReactComponent as GoBackIcon } from 'common/assets/icons/path.svg';
|
|
14
13
|
import { useAppDispatch, useAppSelector } from '../Store/Store';
|
|
14
|
+
import useRequestStore from 'Store/requestStore';
|
|
15
15
|
|
|
16
16
|
const GoBackButton = ({ items, refine }: CurrentRefinementsProvided) => {
|
|
17
17
|
const isMobile = useMediaQuery({ query: '(max-width: 776px)' });
|
|
18
18
|
const dispatch = useAppDispatch();
|
|
19
19
|
const stateGlobal = useAppSelector(state => state);
|
|
20
20
|
const { search } = stateGlobal;
|
|
21
|
-
const {
|
|
22
|
-
|
|
23
|
-
firstSearchImage,
|
|
24
|
-
firstSearchPrefilters,
|
|
25
|
-
firstSearchThumbSearchInput,
|
|
26
|
-
} = search;
|
|
21
|
+
const { firstSearchResults, firstSearchImage, firstSearchPrefilters } =
|
|
22
|
+
search;
|
|
27
23
|
const clearPostFilters = useCallback(() => refine(items), [refine, items]);
|
|
28
24
|
const { t } = useTranslation();
|
|
29
25
|
|
|
26
|
+
const { setRequestImages, resetRegions } = useRequestStore(state => ({
|
|
27
|
+
setRequestImages: state.setRequestImages,
|
|
28
|
+
resetRegions: state.resetRegions,
|
|
29
|
+
}));
|
|
30
30
|
const onGoBack = () => {
|
|
31
31
|
dispatch(setSearchResults(firstSearchResults));
|
|
32
32
|
dispatch(setRequestImage(firstSearchImage));
|
|
33
|
+
setRequestImages([firstSearchImage]);
|
|
33
34
|
dispatch(setPreFilter(firstSearchPrefilters));
|
|
34
35
|
dispatch(clearPostFilter());
|
|
36
|
+
resetRegions();
|
|
35
37
|
clearPostFilters();
|
|
36
|
-
|
|
37
|
-
dispatch(setImageSearchInput(firstSearchThumbSearchInput));
|
|
38
|
-
}
|
|
39
|
-
}
|
|
38
|
+
};
|
|
40
39
|
|
|
41
40
|
return (
|
|
42
41
|
<div
|
|
43
42
|
className={`go-back-button ${isMobile ? 'mobile-view' : ''}`}
|
|
44
43
|
onClick={() => onGoBack()}
|
|
45
44
|
>
|
|
46
|
-
<GoBackIcon width={16} height={16}
|
|
45
|
+
<GoBackIcon width={16} height={16} />
|
|
47
46
|
{t('Back to request image')}
|
|
48
47
|
</div>
|
|
49
|
-
)
|
|
48
|
+
);
|
|
50
49
|
};
|
|
51
50
|
|
|
52
|
-
export const GoBack = connectCurrentRefinements<any>(
|
|
53
|
-
GoBackButton,
|
|
54
|
-
);
|
|
51
|
+
export const GoBack = connectCurrentRefinements<any>(GoBackButton);
|