@nyris/nyris-webapp 0.2.5 → 0.3.2

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 (199) hide show
  1. package/build/asset-manifest.json +32 -18
  2. package/build/index.html +1 -1
  3. package/build/js/test.js +62 -0
  4. package/build/{precache-manifest.497998bf0df450969bab5608621be10a.js → precache-manifest.8f85a4fff2063a7498a608ec69549bb1.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.efc0ab83.chunk.js +3 -0
  11. package/build/static/js/2.efc0ab83.chunk.js.LICENSE.txt +133 -0
  12. package/build/static/js/2.efc0ab83.chunk.js.map +1 -0
  13. package/build/static/js/main.3bfed050.chunk.js +2 -0
  14. package/build/static/js/main.3bfed050.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 +62 -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/DetailItem.tsx +175 -0
  130. package/src/components/DragDropFile.tsx +188 -0
  131. package/src/components/ExampleImages.tsx +32 -17
  132. package/src/components/Feedback.tsx +87 -48
  133. package/src/components/FilterComponent.tsx +33 -0
  134. package/src/components/Footer.tsx +29 -0
  135. package/src/components/FooterMD.tsx +54 -0
  136. package/src/components/FooterNewVersion.tsx +12 -0
  137. package/src/components/FooterResult.tsx +47 -0
  138. package/src/components/Header.tsx +35 -0
  139. package/src/components/HeaderMd.tsx +39 -0
  140. package/src/components/HeaderNewVersion.tsx +92 -0
  141. package/src/components/Layout.tsx +46 -0
  142. package/src/components/LoadingScreen/index.tsx +29 -0
  143. package/src/components/Navigation.tsx +34 -0
  144. package/src/components/Panigation/Pagination.tsx +140 -0
  145. package/src/components/Panigation/cx.js +3 -0
  146. package/src/components/Panigation/isModifierClick.js +10 -0
  147. package/src/components/Result.tsx +186 -113
  148. package/src/components/Saved/AllItem.tsx +32 -0
  149. package/src/components/Saved/Category.tsx +16 -0
  150. package/src/components/carousel/DefaultCarousel.tsx +48 -0
  151. package/src/components/common.d.ts +9 -0
  152. package/src/components/common.scss +54 -0
  153. package/src/components/default-select.tsx +44 -0
  154. package/src/components/hitItem/hits.tsx +50 -0
  155. package/src/components/hitItem/infinitiHits.tsx +33 -0
  156. package/src/components/input/inputSearch.tsx +77 -0
  157. package/src/components/modal/DefaultModal.tsx +28 -0
  158. package/src/components/preview/preview.tsx +433 -0
  159. package/src/components/results/ItemResult.tsx +155 -0
  160. package/src/components/search/ListSearch.tsx +209 -0
  161. package/src/defaults.ts +4 -3
  162. package/src/index.css +577 -306
  163. package/src/index.tsx +39 -187
  164. package/src/modules/LandingPage/common.scss +1304 -0
  165. package/src/modules/LandingPage/indexApp.tsx +474 -0
  166. package/src/modules/LandingPage/indexAppMD.tsx +494 -0
  167. package/src/modules/LandingPage/indexNewVersion.tsx +117 -0
  168. package/src/page/Auth/login.tsx +7 -0
  169. package/src/page/Exception/404.tsx +11 -0
  170. package/src/page/History/index.tsx +76 -0
  171. package/src/page/Profile/index.tsx +87 -0
  172. package/src/page/Saved/MockData.ts +223 -0
  173. package/src/page/Saved/index.tsx +166 -0
  174. package/src/page/Support/index.tsx +160 -0
  175. package/src/page/result/MockData.ts +36 -0
  176. package/src/page/result/index.tsx +473 -0
  177. package/src/services/Feedback.ts +65 -0
  178. package/src/services/findByImage.ts +24 -0
  179. package/src/services/findRegionsCustom.ts +212 -0
  180. package/src/services/image.ts +110 -0
  181. package/src/services/nyris.ts +123 -0
  182. package/src/services/session.ts +20 -0
  183. package/src/services/types.ts +96 -0
  184. package/src/types.ts +43 -3
  185. package/tsconfig.json +3 -8
  186. package/build/static/css/2.43a1c8b7.chunk.css +0 -2
  187. package/build/static/css/2.43a1c8b7.chunk.css.map +0 -1
  188. package/build/static/css/main.f6ed5f12.chunk.css +0 -2
  189. package/build/static/css/main.f6ed5f12.chunk.css.map +0 -1
  190. package/build/static/js/2.a591d52a.chunk.js +0 -3
  191. package/build/static/js/2.a591d52a.chunk.js.LICENSE.txt +0 -79
  192. package/build/static/js/2.a591d52a.chunk.js.map +0 -1
  193. package/build/static/js/main.28bb3581.chunk.js +0 -2
  194. package/build/static/js/main.28bb3581.chunk.js.map +0 -1
  195. package/src/AppMD.tsx +0 -320
  196. package/src/actions/nyrisAppActions.ts +0 -76
  197. package/src/actions/searchActions.ts +0 -143
  198. package/src/epics/index.ts +0 -149
  199. package/src/epics/search.ts +0 -114
@@ -0,0 +1,77 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+ import { Button, Box } from "@material-ui/core";
3
+ import ClearOutlinedIcon from "@material-ui/icons/ClearOutlined";
4
+ import { connectSearchBox } from "react-instantsearch-dom";
5
+ import { useHistory } from "react-router-dom";
6
+ import { useAppDispatch } from "Store/Store";
7
+ import { reset } from "Store/Search";
8
+ import { debounce } from "lodash";
9
+ import { useCallback } from "react";
10
+
11
+ const SearchBox = ({ currentRefinement, isSearchStalled, refine }: any) => {
12
+ const focusInp: any = useRef();
13
+ const history = useHistory();
14
+ const [, setShowBtnClear] = useState<boolean>(true);
15
+ const [valueInput, setValueInput] = useState<string>("");
16
+ const dispatch = useAppDispatch();
17
+
18
+ useEffect(() => {
19
+ if (focusInp?.current) {
20
+ focusInp?.current.focus();
21
+ }
22
+ }, [focusInp]);
23
+
24
+ useEffect(() => {
25
+ // if (currentRefinement) {
26
+ setValueInput(currentRefinement);
27
+ // }
28
+ }, [currentRefinement]);
29
+
30
+ useEffect(() => {
31
+ if (valueInput.length > 0) {
32
+ setShowBtnClear(true);
33
+ }
34
+ setShowBtnClear(false);
35
+ }, [valueInput]);
36
+
37
+ const debounceSearch = useCallback(
38
+ debounce((nextValue: any) => refine(nextValue), 0),
39
+ []
40
+ );
41
+
42
+ return (
43
+ <Box className="wrap-input-search">
44
+ <Box p={2} display={"flex"} className="box-input-search">
45
+ <form noValidate action="" role="search">
46
+ <input
47
+ style={{ border: "0px", width: "100%" }}
48
+ className="input-search"
49
+ value={valueInput}
50
+ onChange={(event) => {
51
+ setValueInput(event.currentTarget.value);
52
+ debounceSearch(event.currentTarget.value);
53
+ }}
54
+ ref={focusInp}
55
+ />
56
+ {history.location.pathname === "/result" && (
57
+ <Button
58
+ className="btn-clear-text"
59
+ onClick={() => {
60
+ setValueInput("");
61
+ refine("");
62
+ dispatch(reset(""));
63
+ history.push("/");
64
+ return;
65
+ }}
66
+ >
67
+ <ClearOutlinedIcon style={{ fontSize: 12, color: "#2B2C46" }} />
68
+ </Button>
69
+ )}
70
+ </form>
71
+ </Box>
72
+ </Box>
73
+ );
74
+ };
75
+
76
+ const CustomSearchBox = connectSearchBox(SearchBox);
77
+ export default CustomSearchBox;
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import Modal from "@material-ui/core/Modal";
3
+
4
+ interface Props {
5
+ children: JSX.Element;
6
+ openModal: boolean;
7
+ handleClose: (e: any) => void;
8
+ }
9
+
10
+ function DefaultModal(props: Props) {
11
+ const { children, openModal = false, handleClose } = props;
12
+
13
+ return (
14
+ <Modal
15
+ open={openModal}
16
+ onClose={handleClose}
17
+ style={{
18
+ display: "flex",
19
+ justifyContent: "center",
20
+ alignItems: "center",
21
+ }}
22
+ >
23
+ {children}
24
+ </Modal>
25
+ );
26
+ }
27
+
28
+ export default DefaultModal;
@@ -0,0 +1,433 @@
1
+ import React from "react";
2
+ import { Layer, Stage, Image, Circle, Rect } from "react-konva";
3
+ import Konva from "konva";
4
+ import { NodeGroup } from "react-move";
5
+
6
+ type PreviewElem = "tl" | "tr" | "bl" | "br" | "rect";
7
+
8
+ interface RectCoords {
9
+ x1: number;
10
+ y1: number;
11
+ x2: number;
12
+ y2: number;
13
+ }
14
+
15
+ interface PreviewProps {
16
+ image: HTMLCanvasElement;
17
+ initialRegion: any;
18
+ regions: any[];
19
+ onSelectionChange?: (r: any) => void;
20
+ maxWidth: number;
21
+ maxHeight: number;
22
+ dotColor: string;
23
+ }
24
+
25
+ interface PreviewState extends RectCoords {
26
+ tlHover: boolean;
27
+ trHover: boolean;
28
+ blHover: boolean;
29
+ brHover: boolean;
30
+ dotHover: boolean;
31
+ rectHover: boolean;
32
+ }
33
+ interface WH {
34
+ w: number;
35
+ h: number;
36
+ }
37
+
38
+ function getThumbSizeLongestEdge(
39
+ maxW: number,
40
+ maxH: number,
41
+ iW: number,
42
+ iH: number
43
+ ): WH {
44
+ let iR = iW / iH;
45
+ let dR = maxW / maxH;
46
+ if (dR > iR) {
47
+ return {
48
+ w: (iW * maxH) / iH,
49
+ h: maxH,
50
+ };
51
+ }
52
+ return {
53
+ w: maxW,
54
+ h: (iH * maxW) / iW,
55
+ };
56
+ }
57
+
58
+ class Preview extends React.Component<PreviewProps, PreviewState> {
59
+ private readonly selectionRef: React.RefObject<any>;
60
+ private animation?: Konva.Animation;
61
+
62
+ private handleDragMoveRect = this.handleDragMove.bind(this, "rect");
63
+ private handleDragMoveTl = this.handleDragMove.bind(this, "tl");
64
+ private handleDragMoveTr = this.handleDragMove.bind(this, "tr");
65
+ private handleDragMoveBl = this.handleDragMove.bind(this, "bl");
66
+ private handleDragMoveBr = this.handleDragMove.bind(this, "br");
67
+
68
+ private handleDragBoundTl = ({ x, y }: { x: number; y: number }) => {
69
+ let [minX, minY] = [100, 100];
70
+ let { x2, y2 } = this.scaleToPreviewPixels(this.state);
71
+ return {
72
+ x: Math.max(Math.min(x, x2 - minX), 0),
73
+ y: Math.max(Math.min(y, y2 - minY), 0),
74
+ };
75
+ };
76
+
77
+ private handleDragBoundTr = ({ x, y }: { x: number; y: number }) => {
78
+ let [minX, minY] = [100, 100];
79
+ let { x1, y2, width } = this.scaleToPreviewPixels(this.state);
80
+ return {
81
+ x: Math.min(Math.max(x, x1 + minX), width),
82
+ y: Math.max(Math.min(y, y2 - minY), 0),
83
+ };
84
+ };
85
+ private handleDragBoundBl = ({ x, y }: { x: number; y: number }) => {
86
+ let [minX, minY] = [100, 100];
87
+ let { x2, y1, height } = this.scaleToPreviewPixels(this.state);
88
+ return {
89
+ x: Math.max(Math.min(x, x2 - minX), 0),
90
+ y: Math.min(Math.max(y, y1 + minY), height),
91
+ };
92
+ };
93
+
94
+ private handleDragBoundBr = ({ x, y }: { x: number; y: number }) => {
95
+ let [minX, minY] = [100, 100];
96
+ let { x1, y1, width, height } = this.scaleToPreviewPixels(this.state);
97
+ return {
98
+ x: Math.min(Math.max(x, x1 + minX), width),
99
+ y: Math.min(Math.max(y, y1 + minY), height),
100
+ };
101
+ };
102
+
103
+ private handleDragBoundRect = ({ x, y }: { x: number; y: number }) => {
104
+ let { x1, x2, y1, y2, width, height } = this.scaleToPreviewPixels(
105
+ this.state
106
+ );
107
+ let elemWidth = x2 - x1;
108
+ let elemHeight = y2 - y1;
109
+ return {
110
+ x: Math.max(Math.min(x, width - elemWidth), 0),
111
+ y: Math.max(Math.min(y, height - elemHeight), 0),
112
+ };
113
+ };
114
+
115
+ constructor(props: PreviewProps) {
116
+ super(props);
117
+ this.selectionRef = React.createRef<Konva.Shape>();
118
+ this.state = {
119
+ tlHover: false,
120
+ trHover: false,
121
+ blHover: false,
122
+ brHover: false,
123
+ dotHover: false,
124
+ rectHover: false,
125
+ ...props.initialRegion,
126
+ };
127
+ }
128
+
129
+ private handleDragMove(
130
+ elem: PreviewElem,
131
+ evt: Konva.KonvaEventObject<DragEvent>
132
+ ) {
133
+ let { x1, x2, y1, y2, width, height } = this.scaleToPreviewPixels(
134
+ this.state
135
+ );
136
+ if (evt.target instanceof Konva.Stage) {
137
+ return;
138
+ }
139
+
140
+ let { x: newX, y: newY } = evt.target.getAbsolutePosition();
141
+ let { width: elemWidth, height: elemHeight } = evt.target.getSize();
142
+ switch (elem) {
143
+ case "rect":
144
+ x1 = newX;
145
+ y1 = newY;
146
+ x2 = newX + elemWidth;
147
+ y2 = newY + elemHeight;
148
+ break;
149
+ case "tl":
150
+ x1 = newX;
151
+ y1 = newY;
152
+ break;
153
+ case "tr":
154
+ x2 = newX;
155
+ y1 = newY;
156
+ break;
157
+ case "bl":
158
+ x1 = newX;
159
+ y2 = newY;
160
+ break;
161
+ case "br":
162
+ x2 = newX;
163
+ y2 = newY;
164
+ break;
165
+ }
166
+ let newState = {
167
+ x1: x1 / width,
168
+ x2: x2 / width,
169
+ y1: y1 / height,
170
+ y2: y2 / height,
171
+ };
172
+ this.setSelection(newState);
173
+ }
174
+
175
+ private scaleToPreviewPixels({ x1, x2, y1, y2 }: any) {
176
+ let { w: width, h: height } = getThumbSizeLongestEdge(
177
+ this.props.maxWidth,
178
+ this.props.maxHeight,
179
+ this.props.image.width,
180
+ this.props.image.height
181
+ );
182
+ return {
183
+ x1: x1 * width,
184
+ x2: x2 * width,
185
+ y1: y1 * height,
186
+ y2: y2 * height,
187
+ width,
188
+ height,
189
+ };
190
+ }
191
+
192
+ componentDidMount(): void {
193
+ let speed = 40;
194
+ this.animation = new Konva.Animation(
195
+ (frame?: { timeDiff: number; time: number }) => {
196
+ if (!frame) {
197
+ return;
198
+ }
199
+ let angleDiff = (frame.time * speed) / 1000;
200
+ this.selectionRef.current.dashOffset(-angleDiff);
201
+ },
202
+ this.selectionRef.current.getLayer()
203
+ );
204
+ this.animation.start();
205
+ }
206
+
207
+ componentWillUnmount(): void {
208
+ this.animation && this.animation.stop();
209
+ }
210
+
211
+ setSelection(r: RectCoords) {
212
+ this.setState(r);
213
+ if (this.props.onSelectionChange) {
214
+ this.props.onSelectionChange(r);
215
+ }
216
+ }
217
+
218
+ getCursor() {
219
+ if (this.state.dotHover) {
220
+ return "pointer";
221
+ }
222
+ if (this.state.tlHover) {
223
+ return "nw-resize";
224
+ }
225
+ if (this.state.trHover) {
226
+ return "ne-resize";
227
+ }
228
+ if (this.state.blHover) {
229
+ return "sw-resize";
230
+ }
231
+ if (this.state.brHover) {
232
+ return "se-resize";
233
+ }
234
+ if (this.state.rectHover) {
235
+ return "move";
236
+ }
237
+ return "default";
238
+ }
239
+
240
+ render() {
241
+ const { image, regions } = this.props;
242
+ if (!image) {
243
+ return null;
244
+ }
245
+
246
+ const { x1, x2, y1, y2, width, height }: any = this.scaleToPreviewPixels(
247
+ this.state
248
+ );
249
+
250
+ const dots = regions.map((region: any, i: any) => {
251
+ let { x1, x2, y1, y2 } = region;
252
+ return {
253
+ // get middle of box and map to pixels
254
+ region,
255
+ x: width * ((x2 - x1) / 2 + x1),
256
+ y: height * ((y2 - y1) / 2 + y1),
257
+ key: i,
258
+ };
259
+ });
260
+
261
+ let gripSize = 40;
262
+ let gripOpacity = 0.3;
263
+ let gripOpacityOver = 0.6;
264
+ let darkOpacity = 0.3;
265
+
266
+ return (
267
+ <Stage
268
+ width={width}
269
+ height={height}
270
+ style={{
271
+ cursor: this.getCursor(),
272
+ width: width,
273
+ height: height,
274
+ margin: "auto",
275
+ marginBottom: "5%",
276
+ }}
277
+ >
278
+ <Layer key="img">
279
+ <Image image={image} width={width} height={height} />
280
+ </Layer>
281
+ <Layer key="selection">
282
+ {/* Selection box */}
283
+ <Rect
284
+ stroke="white"
285
+ strokeWidth={2}
286
+ x={x1}
287
+ y={y1}
288
+ width={x2 - x1}
289
+ height={y2 - y1}
290
+ />
291
+ <Rect
292
+ stroke="black"
293
+ draggable={true}
294
+ onDragMove={this.handleDragMoveRect}
295
+ dragBoundFunc={this.handleDragBoundRect}
296
+ onMouseOver={() => this.setState({ rectHover: true })}
297
+ onMouseOut={() => this.setState({ rectHover: false })}
298
+ opacity={0.8}
299
+ strokeWidth={2}
300
+ x={x1}
301
+ y={y1}
302
+ width={x2 - x1}
303
+ height={y2 - y1}
304
+ dash={[15, 15]}
305
+ ref={this.selectionRef}
306
+ />
307
+ {/* grips */}
308
+ <Rect
309
+ fill="black"
310
+ draggable={true}
311
+ onDragMove={this.handleDragMoveTl}
312
+ dragBoundFunc={this.handleDragBoundTl}
313
+ onMouseOver={() => this.setState({ tlHover: true })}
314
+ onMouseOut={() => this.setState({ tlHover: false })}
315
+ opacity={this.state.tlHover ? gripOpacityOver : gripOpacity}
316
+ width={gripSize}
317
+ height={gripSize}
318
+ x={x1}
319
+ y={y1}
320
+ />
321
+ <Rect
322
+ fill="black"
323
+ draggable={true}
324
+ onDragMove={this.handleDragMoveTr}
325
+ dragBoundFunc={this.handleDragBoundTr}
326
+ onMouseOver={() => this.setState({ trHover: true })}
327
+ onMouseOut={() => this.setState({ trHover: false })}
328
+ opacity={this.state.trHover ? gripOpacityOver : gripOpacity}
329
+ width={gripSize}
330
+ height={gripSize}
331
+ x={x2}
332
+ y={y1}
333
+ offsetX={gripSize}
334
+ />
335
+ <Rect
336
+ fill="black"
337
+ draggable={true}
338
+ onDragMove={this.handleDragMoveBl}
339
+ dragBoundFunc={this.handleDragBoundBl}
340
+ onMouseOver={() => this.setState({ blHover: true })}
341
+ onMouseOut={() => this.setState({ blHover: false })}
342
+ opacity={this.state.blHover ? gripOpacityOver : gripOpacity}
343
+ width={gripSize}
344
+ height={gripSize}
345
+ x={x1}
346
+ y={y2}
347
+ offsetY={gripSize}
348
+ />
349
+ <Rect
350
+ fill="black"
351
+ draggable={true}
352
+ onDragMove={this.handleDragMoveBr}
353
+ dragBoundFunc={this.handleDragBoundBr}
354
+ onMouseOver={() => this.setState({ brHover: true })}
355
+ onMouseOut={() => this.setState({ brHover: false })}
356
+ opacity={this.state.brHover ? gripOpacityOver : gripOpacity}
357
+ width={gripSize}
358
+ height={gripSize}
359
+ x={x2}
360
+ y={y2}
361
+ offsetY={gripSize}
362
+ offsetX={gripSize}
363
+ />
364
+ {/* Dark areas */}
365
+ <Rect
366
+ fill="black"
367
+ opacity={darkOpacity}
368
+ x={0}
369
+ y={0}
370
+ width={width}
371
+ height={y1}
372
+ />
373
+ <Rect
374
+ fill="black"
375
+ opacity={darkOpacity}
376
+ x={0}
377
+ y={y2}
378
+ width={width}
379
+ height={height - y2}
380
+ />
381
+ <Rect
382
+ fill="black"
383
+ opacity={darkOpacity}
384
+ x={0}
385
+ y={y1}
386
+ width={x1}
387
+ height={y2 - y1}
388
+ />
389
+ <Rect
390
+ fill="black"
391
+ opacity={darkOpacity}
392
+ x={x2}
393
+ y={y1}
394
+ width={width - x2}
395
+ height={y2 - y1}
396
+ />
397
+ </Layer>
398
+ <NodeGroup
399
+ data={dots}
400
+ keyAccessor={(r) => r.key}
401
+ start={(d, i) => ({ opacity: 0, x: -100, y: d.y })}
402
+ enter={(d, i) => ({
403
+ opacity: [1],
404
+ x: [d.x],
405
+ y: d.y,
406
+ timing: { delay: i * 100, duration: 300 },
407
+ })}
408
+ >
409
+ {(ds) => (
410
+ <Layer key="dots">
411
+ {ds.map(({ key, data, state: position }) => (
412
+ <Circle
413
+ onClick={() => this.setSelection(data.region)}
414
+ onTap={() => this.setSelection(data.region)}
415
+ onMouseOver={() => this.setState({ dotHover: true })}
416
+ onMouseOut={() => this.setState({ dotHover: false })}
417
+ key={key}
418
+ radius={7}
419
+ {...position}
420
+ stroke={this.props.dotColor}
421
+ fill="white"
422
+ strokeWidth={4}
423
+ />
424
+ ))}
425
+ </Layer>
426
+ )}
427
+ </NodeGroup>
428
+ </Stage>
429
+ );
430
+ }
431
+ }
432
+
433
+ export default Preview;
@@ -0,0 +1,155 @@
1
+ import { Box, Button, Grid, Typography } from "@material-ui/core";
2
+ import React from "react";
3
+ import IconSupport from "common/assets/icons/support.svg";
4
+ import IconLike from "common/assets/icons/icon_like.svg";
5
+ import IconDisLike from "common/assets/icons/icon_dislike.svg";
6
+ import IconShare from "common/assets/icons/Fill.svg";
7
+ import IconBookmark from "common/assets/icons/book_mark.svg";
8
+ import IconModalImage from "common/assets/icons/icon_modal_image.svg";
9
+
10
+ interface Props {
11
+ dataItem: any;
12
+ handlerToggleModal?: any;
13
+ handleClose?: () => void;
14
+ handlerToggleModalShare?: () => void;
15
+ isHover?: boolean;
16
+ indexItem?: number;
17
+ onSearchImage?: any;
18
+ handlerFeedback?: any;
19
+ }
20
+
21
+ function ItemResult(props: Props) {
22
+ const {
23
+ dataItem,
24
+ handlerToggleModal,
25
+ handlerToggleModalShare,
26
+ isHover = false,
27
+ onSearchImage,
28
+ handlerFeedback,
29
+ } = props;
30
+ const { img, sku, title, main_image_link } = dataItem;
31
+
32
+ return (
33
+ <Box className="wrap-main-item-result">
34
+ <Box className="box-top">
35
+ {!isHover && (
36
+ <Box className="box-icon-modal">
37
+ <Button
38
+ onClick={(e: any) => {
39
+ e.preventDefault();
40
+ onSearchImage(main_image_link);
41
+ // handlerToggleModal();
42
+ }}
43
+ >
44
+ <img
45
+ src={IconModalImage}
46
+ alt="icon_modal"
47
+ width={21}
48
+ height={21}
49
+ />
50
+ </Button>
51
+ </Box>
52
+ )}
53
+
54
+ <Box className="box-image">
55
+ <Button
56
+ style={{ width: "100%", height: "100%", padding: 0, zIndex: 9 }}
57
+ onClick={handlerToggleModal}
58
+ >
59
+ <img
60
+ src={img?.url ? img?.url : main_image_link}
61
+ alt="image_item"
62
+ className="img-style"
63
+ />
64
+ </Button>
65
+ {isHover && (
66
+ <Box className="box-hover">
67
+ <Button>View item</Button>
68
+ </Box>
69
+ )}
70
+ </Box>
71
+ </Box>
72
+ <Box
73
+ className="box-content"
74
+ display={"flex"}
75
+ style={{ flexDirection: "column" }}
76
+ >
77
+ <Box className="box-top">
78
+ <Grid container justifyContent="space-between">
79
+ <Grid item xs={10}>
80
+ <Typography className="text-f8 max-line-1">SKU: {sku}</Typography>
81
+ <Typography className="text-f9 text-bold max-line-3">
82
+ {title}
83
+ </Typography>
84
+ </Grid>
85
+ <Grid item>
86
+ <Button className="btn-item">
87
+ <img
88
+ src={IconBookmark}
89
+ alt="image_item"
90
+ className="icon_action"
91
+ />
92
+ </Button>
93
+ </Grid>
94
+ </Grid>
95
+ </Box>
96
+
97
+ <Box className="box-bottom">
98
+ <Grid container justifyContent="space-between" alignItems="center">
99
+ <Grid item>
100
+ <Box display={"flex"} alignItems={"center"}>
101
+ <Button
102
+ className="btn-item"
103
+ onClick={() => handlerFeedback("like")}
104
+ >
105
+ <img
106
+ src={IconLike}
107
+ alt="image_item"
108
+ className="icon_action"
109
+ />
110
+ </Button>
111
+ <Button
112
+ className="btn-item"
113
+ onClick={() => handlerFeedback("dislike")}
114
+ >
115
+ <img
116
+ src={IconDisLike}
117
+ alt="image_item"
118
+ className="icon_action"
119
+ />
120
+ </Button>
121
+ </Box>
122
+ </Grid>
123
+ <Grid item>
124
+ <Box display={"flex"} alignItems={"center"}>
125
+ <Button className="btn-item" onClick={handlerToggleModalShare}>
126
+ <img
127
+ src={IconShare}
128
+ alt="image_item"
129
+ className="icon_action"
130
+ />
131
+ </Button>
132
+ <Button className="btn-item">
133
+ <Box
134
+ className="box-gray text-center box-support"
135
+ display={"flex"}
136
+ justifyContent={"center"}
137
+ alignItems={"center"}
138
+ >
139
+ <img
140
+ src={IconSupport}
141
+ alt="image_item"
142
+ className="icon_support"
143
+ />
144
+ </Box>
145
+ </Button>
146
+ </Box>
147
+ </Grid>
148
+ </Grid>
149
+ </Box>
150
+ </Box>
151
+ </Box>
152
+ );
153
+ }
154
+
155
+ export default ItemResult;