@nyris/nyris-webapp 0.2.6 → 0.3.3

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 (200) hide show
  1. package/build/asset-manifest.json +32 -18
  2. package/build/index.html +1 -1
  3. package/build/js/test.js +56 -0
  4. package/build/{precache-manifest.aa7c9d32340f77d86c9a3347b54ba2a5.js → precache-manifest.01ce682577e62add75aa397b2a944b75.js} +89 -13
  5. package/build/service-worker.js +1 -1
  6. package/build/static/css/2.8285176a.chunk.css +2 -0
  7. package/build/static/css/2.8285176a.chunk.css.map +1 -0
  8. package/build/static/css/main.6676fe1f.chunk.css +2 -0
  9. package/build/static/css/main.6676fe1f.chunk.css.map +1 -0
  10. package/build/static/js/2.d1562c08.chunk.js +3 -0
  11. package/build/static/js/2.d1562c08.chunk.js.LICENSE.txt +133 -0
  12. package/build/static/js/2.d1562c08.chunk.js.map +1 -0
  13. package/build/static/js/main.5c08aba4.chunk.js +2 -0
  14. package/build/static/js/main.5c08aba4.chunk.js.map +1 -0
  15. package/build/static/js/{runtime-main.f5553a9b.js → runtime-main.b418ff16.js} +1 -1
  16. package/build/static/js/{runtime-main.f5553a9b.js.map → runtime-main.b418ff16.js.map} +1 -1
  17. package/build/static/media/Fill.37094b44.svg +3 -0
  18. package/build/static/media/Montserrat-Bold.5a052e98.otf +0 -0
  19. package/build/static/media/Montserrat-Light.21789e89.otf +0 -0
  20. package/build/static/media/Montserrat-Medium.a53e0373.otf +0 -0
  21. package/build/static/media/Montserrat-Regular.71cdc681.otf +0 -0
  22. package/build/static/media/Montserrat-SemiBold.f613d915.otf +0 -0
  23. package/build/static/media/Rectangle.4dd8b747.png +0 -0
  24. package/build/static/media/admin.9529c7f6.svg +3 -0
  25. package/build/static/media/bg-support-page.6ac55268.svg +9 -0
  26. package/build/static/media/book_mark.8e294c0b.svg +3 -0
  27. package/build/static/media/icon_dislike.94607ca6.svg +3 -0
  28. package/build/static/media/icon_like.a4fb1b18.svg +3 -0
  29. package/build/static/media/icon_modal_image.3068d0ea.svg +21 -0
  30. package/build/static/media/icon_search_image.c2c728c0.svg +3 -0
  31. package/build/static/media/nyris_logo.22d8f250.svg +3 -0
  32. package/build/static/media/reload_icon.4b579a74.svg +3 -0
  33. package/build/static/media/save_search.bebaeebf.svg +3 -0
  34. package/build/static/media/support.289c3a3c.svg +3 -0
  35. package/build/static/media/translate_icon.f0492297.svg +3 -0
  36. package/package.json +30 -6
  37. package/public/js/test.js +56 -0
  38. package/src/App.css +27 -11
  39. package/src/App.tsx +19 -235
  40. package/src/Router.tsx +97 -0
  41. package/src/Store/Auth.ts +44 -0
  42. package/src/Store/Nyris.ts +77 -0
  43. package/src/Store/Search.ts +269 -0
  44. package/src/Store/Store.ts +46 -0
  45. package/src/Store/common.d.ts +10 -0
  46. package/src/{epics → Store/epics}/feedback.ts +0 -0
  47. package/src/{epics → Store/epics}/types.ts +1 -1
  48. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Bold.otf +0 -0
  49. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Light.otf +0 -0
  50. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Medium.otf +0 -0
  51. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-Regular.otf +0 -0
  52. package/src/common/assets/fonts/Montserrat_OTF/Montserrat-SemiBold.otf +0 -0
  53. package/src/{fonts → common/assets/fonts}/roboto-bold-webfont.woff +0 -0
  54. package/src/{fonts → common/assets/fonts}/roboto-bold-webfont.woff2 +0 -0
  55. package/src/{fonts → common/assets/fonts}/roboto-italic-webfont.woff +0 -0
  56. package/src/{fonts → common/assets/fonts}/roboto-italic-webfont.woff2 +0 -0
  57. package/src/{fonts → common/assets/fonts}/roboto-regular-webfont.woff +0 -0
  58. package/src/{fonts → common/assets/fonts}/roboto-regular-webfont.woff2 +0 -0
  59. package/src/{fonts → common/assets/fonts}/robotocondensed-bold-webfont.woff +0 -0
  60. package/src/{fonts → common/assets/fonts}/robotocondensed-bold-webfont.woff2 +0 -0
  61. package/src/{fonts → common/assets/fonts}/robotocondensed-bolditalic-webfont.woff +0 -0
  62. package/src/{fonts → common/assets/fonts}/robotocondensed-bolditalic-webfont.woff2 +0 -0
  63. package/src/common/assets/icons/Fill.png +0 -0
  64. package/src/common/assets/icons/Fill.svg +3 -0
  65. package/src/common/assets/icons/Icon_wechat.png +0 -0
  66. package/src/common/assets/icons/Icon_whatsapp.png +0 -0
  67. package/src/common/assets/icons/admin.png +0 -0
  68. package/src/common/assets/icons/admin.svg +3 -0
  69. package/src/common/assets/icons/book_mark.png +0 -0
  70. package/src/common/assets/icons/book_mark.svg +3 -0
  71. package/src/common/assets/icons/icon_barcode.png +0 -0
  72. package/src/common/assets/icons/icon_camera.png +0 -0
  73. package/src/common/assets/icons/icon_dislike.svg +3 -0
  74. package/src/common/assets/icons/icon_disslike.png +0 -0
  75. package/src/common/assets/icons/icon_email.png +0 -0
  76. package/src/common/assets/icons/icon_like.png +0 -0
  77. package/src/common/assets/icons/icon_like.svg +3 -0
  78. package/src/common/assets/icons/icon_modal_image.png +0 -0
  79. package/src/common/assets/icons/icon_modal_image.svg +21 -0
  80. package/src/common/assets/icons/icon_picture.png +0 -0
  81. package/src/common/assets/icons/icon_search_image.png +0 -0
  82. package/src/common/assets/icons/icon_search_image.svg +3 -0
  83. package/src/common/assets/icons/nyris_logo.svg +3 -0
  84. package/src/common/assets/icons/reload_icon.png +0 -0
  85. package/src/common/assets/icons/reload_icon.svg +3 -0
  86. package/src/common/assets/icons/save_search.png +0 -0
  87. package/src/common/assets/icons/save_search.svg +3 -0
  88. package/src/common/assets/icons/setting_search_icon.png +0 -0
  89. package/src/common/assets/icons/support.png +0 -0
  90. package/src/common/assets/icons/support.svg +3 -0
  91. package/src/common/assets/icons/translate_icon.png +0 -0
  92. package/src/common/assets/icons/translate_icon.svg +3 -0
  93. package/src/common/assets/icons/view_off.png +0 -0
  94. package/src/common/assets/images/Rectangle.png +0 -0
  95. package/src/common/assets/images/bg-support-page.svg +9 -0
  96. package/src/{images → common/assets/images}/fav/android-icon-192x192.png +0 -0
  97. package/src/{images → common/assets/images}/fav/apple-icon-114x114.png +0 -0
  98. package/src/{images → common/assets/images}/fav/apple-icon-120x120.png +0 -0
  99. package/src/{images → common/assets/images}/fav/apple-icon-144x144.png +0 -0
  100. package/src/{images → common/assets/images}/fav/apple-icon-152x152.png +0 -0
  101. package/src/{images → common/assets/images}/fav/apple-icon-180x180.png +0 -0
  102. package/src/{images → common/assets/images}/fav/apple-icon-57x57.png +0 -0
  103. package/src/{images → common/assets/images}/fav/apple-icon-60x60.png +0 -0
  104. package/src/{images → common/assets/images}/fav/apple-icon-72x72.png +0 -0
  105. package/src/{images → common/assets/images}/fav/apple-icon-76x76.png +0 -0
  106. package/src/{images → common/assets/images}/fav/browserconfig.xml +0 -0
  107. package/src/{images → common/assets/images}/fav/favicon-16x16.png +0 -0
  108. package/src/{images → common/assets/images}/fav/favicon-32x32.png +0 -0
  109. package/src/{images → common/assets/images}/fav/favicon-96x96.png +0 -0
  110. package/src/{images → common/assets/images}/fav/manifest.json +0 -0
  111. package/src/{images → common/assets/images}/ic_cam.png +0 -0
  112. package/src/{images → common/assets/images}/ic_cam.svg +0 -0
  113. package/src/{images → common/assets/images}/ic_cam_large.png +0 -0
  114. package/src/{images → common/assets/images}/ic_cam_large.svg +0 -0
  115. package/src/{images → common/assets/images}/ic_cam_large_noimage.png +0 -0
  116. package/src/{images → common/assets/images}/ic_close_feedback.png +0 -0
  117. package/src/{images → common/assets/images}/ic_close_feedback.svg +0 -0
  118. package/src/{images → common/assets/images}/ic_shopNow.png +0 -0
  119. package/src/{images → common/assets/images}/ic_shopNow.svg +0 -0
  120. package/src/{images → common/assets/images}/ic_shopNowLight.png +0 -0
  121. package/src/{images → common/assets/images}/ic_shopNowLight.svg +0 -0
  122. package/src/common/assets/images/image_test.png +0 -0
  123. package/src/{images → common/assets/images}/nyris_logo.png +0 -0
  124. package/src/{images → common/assets/images}/rewe.svg +0 -0
  125. package/src/{images → common/assets/images}/sectionTransBack.png +0 -0
  126. package/src/{images → common/assets/images}/sectionTransBack.svg +0 -0
  127. package/src/{images → common/assets/images}/sectionTransTop.png +0 -0
  128. package/src/{images → common/assets/images}/sectionTransTop.svg +0 -0
  129. package/src/components/CustomHits/index.tsx +57 -0
  130. package/src/components/DetailItem.tsx +175 -0
  131. package/src/components/DragDropFile.tsx +188 -0
  132. package/src/components/ExampleImages.tsx +32 -17
  133. package/src/components/Feedback.tsx +87 -48
  134. package/src/components/FilterComponent.tsx +33 -0
  135. package/src/components/Footer.tsx +29 -0
  136. package/src/components/FooterMD.tsx +54 -0
  137. package/src/components/FooterNewVersion.tsx +12 -0
  138. package/src/components/FooterResult.tsx +47 -0
  139. package/src/components/Header.tsx +35 -0
  140. package/src/components/HeaderMd.tsx +39 -0
  141. package/src/components/HeaderNewVersion.tsx +92 -0
  142. package/src/components/Layout.tsx +46 -0
  143. package/src/components/LoadingScreen/index.tsx +29 -0
  144. package/src/components/Navigation.tsx +34 -0
  145. package/src/components/Panigation/Pagination.tsx +140 -0
  146. package/src/components/Panigation/cx.js +3 -0
  147. package/src/components/Panigation/isModifierClick.js +10 -0
  148. package/src/components/Result.tsx +186 -113
  149. package/src/components/Saved/AllItem.tsx +32 -0
  150. package/src/components/Saved/Category.tsx +16 -0
  151. package/src/components/carousel/DefaultCarousel.tsx +48 -0
  152. package/src/components/common.d.ts +9 -0
  153. package/src/components/common.scss +54 -0
  154. package/src/components/default-select.tsx +44 -0
  155. package/src/components/hitItem/hits.tsx +50 -0
  156. package/src/components/hitItem/infinitiHits.tsx +33 -0
  157. package/src/components/input/inputSearch.tsx +77 -0
  158. package/src/components/modal/DefaultModal.tsx +28 -0
  159. package/src/components/preview/preview.tsx +433 -0
  160. package/src/components/results/ItemResult.tsx +155 -0
  161. package/src/components/search/ListSearch.tsx +209 -0
  162. package/src/defaults.ts +4 -3
  163. package/src/index.css +577 -306
  164. package/src/index.tsx +39 -187
  165. package/src/modules/LandingPage/common.scss +1304 -0
  166. package/src/modules/LandingPage/indexApp.tsx +492 -0
  167. package/src/modules/LandingPage/indexAppMD.tsx +501 -0
  168. package/src/modules/LandingPage/indexNewVersion.tsx +117 -0
  169. package/src/page/Auth/login.tsx +7 -0
  170. package/src/page/Exception/404.tsx +11 -0
  171. package/src/page/History/index.tsx +76 -0
  172. package/src/page/Profile/index.tsx +87 -0
  173. package/src/page/Saved/MockData.ts +223 -0
  174. package/src/page/Saved/index.tsx +166 -0
  175. package/src/page/Support/index.tsx +160 -0
  176. package/src/page/result/MockData.ts +36 -0
  177. package/src/page/result/index.tsx +473 -0
  178. package/src/services/Feedback.ts +65 -0
  179. package/src/services/findByImage.ts +24 -0
  180. package/src/services/findRegionsCustom.ts +212 -0
  181. package/src/services/image.ts +110 -0
  182. package/src/services/nyris.ts +123 -0
  183. package/src/services/session.ts +20 -0
  184. package/src/services/types.ts +96 -0
  185. package/src/types.ts +43 -3
  186. package/tsconfig.json +3 -8
  187. package/build/static/css/2.43a1c8b7.chunk.css +0 -2
  188. package/build/static/css/2.43a1c8b7.chunk.css.map +0 -1
  189. package/build/static/css/main.f6ed5f12.chunk.css +0 -2
  190. package/build/static/css/main.f6ed5f12.chunk.css.map +0 -1
  191. package/build/static/js/2.a591d52a.chunk.js +0 -3
  192. package/build/static/js/2.a591d52a.chunk.js.LICENSE.txt +0 -79
  193. package/build/static/js/2.a591d52a.chunk.js.map +0 -1
  194. package/build/static/js/main.5a3dcfb4.chunk.js +0 -2
  195. package/build/static/js/main.5a3dcfb4.chunk.js.map +0 -1
  196. package/src/AppMD.tsx +0 -320
  197. package/src/actions/nyrisAppActions.ts +0 -76
  198. package/src/actions/searchActions.ts +0 -143
  199. package/src/epics/index.ts +0 -149
  200. package/src/epics/search.ts +0 -114
@@ -0,0 +1,492 @@
1
+ import "App.css";
2
+ import React, { useCallback, useEffect, useState } from "react";
3
+ import Result from "components/Result";
4
+ import ExampleImages from "components/ExampleImages";
5
+ import CategoryFilter from "components/CategoryFilter";
6
+ import PredictedCategories from "components/PredictedCategories";
7
+ import Codes from "components/Codes";
8
+ import {
9
+ Code,
10
+ CategoryPrediction,
11
+ RectCoords,
12
+ Region,
13
+ cadExtensions,
14
+ isCadFile,
15
+ isImageFile,
16
+ ImageSearchOptions,
17
+ } from "@nyris/nyris-api";
18
+ import { useDropzone } from "react-dropzone";
19
+ import classNames from "classnames";
20
+ import { Animate, NodeGroup } from "react-move";
21
+ import { AppSettings, MDSettings, CanvasWithId } from "types";
22
+ import {
23
+ makeFileHandler,
24
+ Capture,
25
+ } from "@nyris/nyris-react-components";
26
+ import { Snackbar } from "@material-ui/core";
27
+ import MuiAlert, { AlertProps } from "@material-ui/lab/Alert";
28
+
29
+ import { useAppDispatch, useAppSelector } from "Store/Store";
30
+ import {
31
+ loadCadFileLoad,
32
+ loadFile,
33
+ loadFileSelectRegion,
34
+ loadingActionRegions,
35
+ loadingActionResults,
36
+ searchFileImageNonRegion,
37
+ } from "Store/Search";
38
+ import {
39
+ NyrisAppPart,
40
+ NyrisFeedbackState,
41
+ showCamera,
42
+ showFeedback,
43
+ showResults,
44
+ showStart,
45
+ } from "Store/Nyris";
46
+ import { serviceImage, serviceImageNonRegion } from "services/image";
47
+ import { findByImage } from "services/findByImage";
48
+ import { debounce, isEmpty } from "lodash";
49
+ import { feedbackClickEpic } from "services/Feedback";
50
+ import Preview from "components/preview/preview";
51
+ export interface AppHandlers {
52
+ onExampleImageClick: (url: string) => void;
53
+ onImageClick: (position: number, url: string) => void;
54
+ onLinkClick: (position: number, url: string) => void;
55
+ onFileDropped: (file: File) => void;
56
+ onCaptureComplete: (image: HTMLCanvasElement) => void;
57
+ onCaptureCanceled: () => void;
58
+ onSelectFile: (f: File) => void;
59
+ onCameraClick: () => void;
60
+ onShowStart: () => void;
61
+ onSelectionChange: (r: RectCoords) => void;
62
+ onPositiveFeedback: () => void;
63
+ onNegativeFeedback: () => void;
64
+ onCloseFeedback: () => void;
65
+ }
66
+
67
+ export interface AppProps {
68
+ search: {
69
+ results: any[];
70
+ requestId?: string;
71
+ duration?: number;
72
+ categoryPredictions: CategoryPrediction[];
73
+ codes: Code[];
74
+ filterOptions: string[];
75
+ errorMessage?: string;
76
+ regions: Region[];
77
+ previewSelection: RectCoords;
78
+ toastErrorMessage?: string;
79
+ };
80
+ previewImage?: CanvasWithId;
81
+ settings: AppSettings;
82
+ loading: boolean;
83
+ showPart: NyrisAppPart;
84
+ feedbackState: NyrisFeedbackState;
85
+ handlers: AppHandlers;
86
+ mdSettings: MDSettings;
87
+ }
88
+
89
+ function Alert(props: AlertProps) {
90
+ return <MuiAlert elevation={6} variant="filled" {...props} />;
91
+ }
92
+
93
+ const LandingPageApp = () => {
94
+ const dispatch = useAppDispatch();
95
+ const searchState = useAppSelector((state) => state);
96
+ const [toastOpen, setToastOpen] = useState(false);
97
+ const [rectCoords, setRectCoords] = useState<any>(undefined);
98
+ const { settings, search, nyris } = searchState;
99
+ const {
100
+ errorMessage,
101
+ results,
102
+ requestId,
103
+ fetchingRegions,
104
+ fetchingResults,
105
+ requestImage,
106
+ regions,
107
+ selectedRegion,
108
+ categoryPredictions,
109
+ codes,
110
+ filterOptions,
111
+ duration,
112
+ } = search;
113
+ const { showPart } = nyris;
114
+
115
+ const { getRootProps, getInputProps, isDragActive } = useDropzone({
116
+ onDrop: (fs: File[]) => {
117
+ // console.log("fsssssssss", fs);
118
+ serviceImage(fs[0], searchState).then((res) => {
119
+ dispatch(loadFile(res));
120
+ return dispatch(showFeedback(""));
121
+ });
122
+ // return dispatch(loadFile(fs[0]));
123
+ },
124
+ });
125
+ // const minPreviewHeight = 400;
126
+ // const halfOfTheScreenHeight = Math.floor(window.innerHeight * 0.45);
127
+ // const maxPreviewHeight = Math.max(minPreviewHeight, halfOfTheScreenHeight);
128
+
129
+ useEffect(() => {
130
+ if (isEmpty(rectCoords)) {
131
+ return;
132
+ }
133
+ onSearchOffersForImage(rectCoords);
134
+ // eslint-disable-next-line react-hooks/exhaustive-deps
135
+ }, [rectCoords]);
136
+
137
+ const acceptTypes = ["image/*"]
138
+ .concat(settings.cadSearch ? cadExtensions : [])
139
+ .join(",");
140
+
141
+ useEffect(() => {
142
+ if (errorMessage !== "") {
143
+ setToastOpen(true);
144
+ }
145
+ }, [errorMessage]);
146
+
147
+ function scrollTop() {
148
+ // TODO might require polyfill for ios and edge
149
+ window.scrollTo({ top: 0, left: 0, behavior: "smooth" });
150
+ }
151
+
152
+ const onShowStart = () => {
153
+ dispatch(showStart(""));
154
+ scrollTop();
155
+ };
156
+
157
+ const onLinkClick = (_position: number, url: string) => {
158
+ feedbackClickEpic(searchState, _position);
159
+ if (url) {
160
+ window.open(url);
161
+ }
162
+ };
163
+ // TODO: search image file home page
164
+ const isCheckImageFile = (file: any) => {
165
+ dispatch(showResults(""));
166
+ dispatch(loadingActionResults(""));
167
+ dispatch(showFeedback(""));
168
+ if (isImageFile(file) || typeof file === "string") {
169
+ return serviceImage(file, searchState).then((res) => {
170
+ return dispatch(loadFile(res));
171
+ });
172
+ }
173
+ if (isCadFile(file)) {
174
+ return dispatch(loadCadFileLoad(file));
175
+ }
176
+ };
177
+ //
178
+
179
+ const getUrlToCanvasFile = (url: string, position?: number) => {
180
+ dispatch(showResults(""));
181
+ dispatch(loadingActionResults(""));
182
+ if (position) {
183
+ feedbackClickEpic(searchState, position);
184
+ }
185
+
186
+ if (settings.regions) {
187
+ serviceImage(url, searchState).then((res) => {
188
+ dispatch(loadFile(res));
189
+ return dispatch(showFeedback(""));
190
+ });
191
+ } else {
192
+ serviceImageNonRegion(url, searchState, rectCoords).then((res) => {
193
+ dispatch(searchFileImageNonRegion(res));
194
+ });
195
+ }
196
+ };
197
+
198
+ const handlerRectCoords = debounce((value) => {
199
+ return setRectCoords(value);
200
+ }, 1200);
201
+
202
+ const debounceRectCoords = useCallback(
203
+ (value) => handlerRectCoords(value),
204
+ // eslint-disable-next-line react-hooks/exhaustive-deps
205
+ []
206
+ );
207
+
208
+ const onSearchOffersForImage = (r: RectCoords) => {
209
+ const { canvas }: any = requestImage;
210
+ let options: ImageSearchOptions = {
211
+ cropRect: r,
212
+ };
213
+ dispatch(loadingActionRegions(""));
214
+ return findByImage(canvas, options, settings).then((res) => {
215
+ dispatch(loadFileSelectRegion(res));
216
+ return dispatch(showFeedback(""));
217
+ });
218
+ };
219
+
220
+ return (
221
+ <div>
222
+ {showPart === "camera" && (
223
+ <Capture
224
+ onCaptureComplete={(image: HTMLCanvasElement) => {
225
+ return isCheckImageFile(image);
226
+ }}
227
+ onCaptureCanceled={() => dispatch(showStart)}
228
+ useAppText="Use default camera app"
229
+ />
230
+ )}
231
+ <div
232
+ className={classNames("headSection", {
233
+ hidden: showPart === "results",
234
+ })}
235
+ id="headSection"
236
+ >
237
+ <div
238
+ {...getRootProps({
239
+ onClick: (e) => {
240
+ e.stopPropagation();
241
+ },
242
+ })}
243
+ className={classNames("wrapper", "dragAndDropActionArea", {
244
+ fileIsHover: isDragActive,
245
+ })}
246
+ >
247
+ <div className="contentWrap">
248
+ <section className="uploadImage">
249
+ <input
250
+ type="button"
251
+ name="file"
252
+ id="capture"
253
+ className="inputfile"
254
+ accept="image/*"
255
+ capture="environment"
256
+ onClick={() => dispatch(showCamera)}
257
+ />
258
+ <input
259
+ type="file"
260
+ name="file"
261
+ id="capture_file"
262
+ className="inputfile"
263
+ accept={acceptTypes}
264
+ capture="environment"
265
+ />
266
+ <input
267
+ {...getInputProps()}
268
+ type="file"
269
+ name="file"
270
+ id="select_file"
271
+ className="inputfile"
272
+ accept={acceptTypes}
273
+ onChange={makeFileHandler((e) => {
274
+ return isCheckImageFile(e);
275
+ })}
276
+ />
277
+ <div className="onDesktop">
278
+ Drop an image
279
+ <div className="smallText">or</div>
280
+ </div>
281
+ <div className="onMobile camIcon">
282
+ <img src="./images/ic_cam_large.svg" alt="Camera" />
283
+ </div>
284
+ <label
285
+ htmlFor="capture"
286
+ className="btn primary onMobile"
287
+ style={{ marginBottom: "2em", width: "22em" }}
288
+ >
289
+ <span className="onMobile">Take a picture</span>
290
+ </label>
291
+ <br />
292
+ <label
293
+ htmlFor="select_file"
294
+ className="btn primary"
295
+ style={{ width: "22em" }}
296
+ >
297
+ <span>Select a file</span>
298
+ </label>
299
+ <label
300
+ htmlFor="capture"
301
+ className="mobileUploadHandler onMobile"
302
+ />
303
+ </section>
304
+ <ExampleImages
305
+ images={settings.exampleImages}
306
+ onExampleImageClicked={(url: string) => {
307
+ return getUrlToCanvasFile(url);
308
+ }}
309
+ />
310
+ </div>
311
+ </div>
312
+ <div
313
+ className={classNames("tryDifferent", {
314
+ hidden: showPart !== "results",
315
+ })}
316
+ onClick={() => onShowStart()}
317
+ >
318
+ <div className="icIcon"></div>
319
+ <div className="textDesc"> Try a different image</div>
320
+ <br style={{ clear: "both" }} />
321
+ </div>
322
+ <div className="headerSeparatorTop" />
323
+ <div className="headerSeparatorBack" />
324
+ </div>
325
+
326
+ <section
327
+ className={classNames(
328
+ "results",
329
+ { resultsActive: showPart === "results" },
330
+ results.length === 1 ? "singleProduct" : "multipleProducts"
331
+ )}
332
+ >
333
+ {errorMessage && (
334
+ <div className="errorMsg">
335
+ {errorMessage}
336
+ <div
337
+ style={{
338
+ textAlign: "center",
339
+ fontSize: "0.7em",
340
+ paddingTop: "0.8em",
341
+ }}
342
+ >
343
+ <span>
344
+ Make sure to include the request ID when reporting a problem:{" "}
345
+ {requestId}
346
+ </span>
347
+ </div>
348
+ </div>
349
+ )}
350
+ <Animate
351
+ show={fetchingRegions || fetchingResults}
352
+ start={{ opacity: 0.0 }}
353
+ enter={{ opacity: [1.0], timing: { duration: 300 } }}
354
+ leave={{ opacity: [0.0], timing: { duration: 300 } }}
355
+ >
356
+ {(s) => (
357
+ <div className="loadingOverlay" style={{ ...s }}>
358
+ <div className="loading" />
359
+ </div>
360
+ )}
361
+ </Animate>
362
+ {/* // TODO:Box Preview image. */}
363
+ {settings.preview && requestImage && (
364
+ <div className="preview">
365
+ {/* <Preview
366
+ key={requestImage?.id}
367
+ maxWidth={document.body.clientWidth}
368
+ maxHeight={maxPreviewHeight}
369
+ dotColor="#4C8F9F"
370
+ onSelectionChange={(r: RectCoords) => {
371
+ dispatch(selectionChanged(r));
372
+ return debounceRectCoords(r);
373
+ }}
374
+ regions={regions}
375
+ selection={selectedRegion}
376
+ image={requestImage.canvas}
377
+ /> */}
378
+ <Preview
379
+ key={requestImage?.id}
380
+ onSelectionChange={(r: RectCoords) => {
381
+ debounceRectCoords(r);
382
+ return;
383
+ }}
384
+ image={requestImage?.canvas}
385
+ initialRegion={
386
+ !selectedRegion
387
+ ? regions[0]
388
+ ? regions[0]
389
+ : { x1: 0, x2: 1, y1: 0, y2: 1 }
390
+ : selectedRegion
391
+ }
392
+ regions={regions}
393
+ maxWidth={400}
394
+ maxHeight={500}
395
+ dotColor="#FBD914"
396
+ />
397
+ </div>
398
+ )}
399
+ <div className="predicted-categories">
400
+ <PredictedCategories cs={categoryPredictions} />
401
+ </div>
402
+ <div className="predicted-categories">
403
+ <Codes codes={codes} />
404
+ </div>
405
+ <CategoryFilter cats={filterOptions} />
406
+ <div className="wrapper">
407
+ <NodeGroup
408
+ data={results}
409
+ keyAccessor={(r) => r.sku}
410
+ start={(r, i) => ({ opacity: 0, translateX: -100 })}
411
+ enter={(r, i) => ({
412
+ opacity: [1],
413
+ translateX: [0],
414
+ timing: { delay: i * 100, duration: 300 },
415
+ })}
416
+ >
417
+ {(rs) => (
418
+ <>
419
+ {rs.map(({ key, data, state }) => (
420
+ <Result
421
+ key={key}
422
+ noImageUrl={settings.noImageUrl}
423
+ template={settings.resultTemplate}
424
+ onImageClick={(_pos, url) => {
425
+ return getUrlToCanvasFile(url, _pos);
426
+ }}
427
+ onLinkClick={onLinkClick}
428
+ result={data}
429
+ style={{
430
+ opacity: state.opacity,
431
+ transform: `translateX(${state.translateX}%)`,
432
+ }}
433
+ />
434
+ ))}
435
+ </>
436
+ )}
437
+ </NodeGroup>
438
+
439
+ {(results.length === 0 &&
440
+ showPart === "results" &&
441
+ fetchingRegions) ||
442
+ (fetchingResults && (
443
+ <div className="noResults">
444
+ We did not find anything{" "}
445
+ <span role="img" aria-label="sad face">
446
+ 😕
447
+ </span>
448
+ </div>
449
+ ))}
450
+
451
+ <br style={{ clear: "both" }} />
452
+
453
+ {duration && showPart === "results" && (
454
+ <div
455
+ style={{
456
+ textAlign: "center",
457
+ fontSize: "0.7em",
458
+ paddingTop: "0.8em",
459
+ }}
460
+ >
461
+ Search took {duration.toFixed(2)} seconds
462
+ </div>
463
+ )}
464
+
465
+ {requestId && showPart === "results" && (
466
+ <div
467
+ style={{
468
+ textAlign: "center",
469
+ fontSize: "0.7em",
470
+ paddingTop: "0.8em",
471
+ }}
472
+ >
473
+ Request identifier {requestId}
474
+ </div>
475
+ )}
476
+ </div>
477
+ </section>
478
+
479
+ <Snackbar
480
+ open={toastOpen}
481
+ autoHideDuration={3000}
482
+ onClose={() => setToastOpen(false)}
483
+ >
484
+ <Alert onClose={() => setToastOpen(false)} severity="error">
485
+ {errorMessage}
486
+ </Alert>
487
+ </Snackbar>
488
+ </div>
489
+ );
490
+ };
491
+
492
+ export default LandingPageApp;