Compare commits
124 Commits
59a279f924
...
current-de
Author | SHA1 | Date | |
---|---|---|---|
16a5a1f548 | |||
a763c5a69a | |||
a7c58b2609 | |||
3b8ec8e100 | |||
94136c97e6 | |||
4810412bd7 | |||
3f46d60720 | |||
d49a2eb0c8 | |||
8de343016f | |||
470bf6ec67 | |||
dea1eb6104 | |||
ee20b49993 | |||
0e04e19c1b | |||
bd4bfacd66 | |||
1bdabd32bf | |||
2d861de330 | |||
60aa8c7301 | |||
13df697614 | |||
79299d1177 | |||
68a2df23c4 | |||
291e6a4a5d | |||
0d436e71e4 | |||
7a55188904 | |||
3e80159c44 | |||
363d43e04c | |||
a1da184bb0 | |||
066cd569d3 | |||
86a784bee2 | |||
adf6ff4a1d | |||
9ffb981b67 | |||
0860591d28 | |||
4a20d5e4fa | |||
1434792d42 | |||
ade31b767a | |||
fafab29d25 | |||
10ffb1f7f1 | |||
75cf13d945 | |||
a3e39b75d8 | |||
271374b6c6 | |||
811ef4f69d | |||
c532302f73 | |||
36bdaf15e5 | |||
7400319650 | |||
7580006e05 | |||
93d5ab015a | |||
90274e8b17 | |||
9f98a0fea2 | |||
1e950e9de0 | |||
a3bcfc7cf7 | |||
140d4689fe | |||
b19e00d98f | |||
3580e25457 | |||
9a0364e686 | |||
3e54f947b4 | |||
35f76abe60 | |||
caaee74810 | |||
c9dafd95a9 | |||
c14590a0cb | |||
5ad50a8ed0 | |||
56344fa26e | |||
f76e448951 | |||
42b597d585 | |||
77628b0de4 | |||
6e6d3d1823 | |||
2a5991da1f | |||
6afccb19d8 | |||
43ca1b54f1 | |||
923a84e488 | |||
3013dd1bd2 | |||
882bdfcc24 | |||
f180586eb3 | |||
78f2b34810 | |||
f2ad6b43bd | |||
727d55798a | |||
8797ba0778 | |||
176dd29625 | |||
2ed0be6664 | |||
012ef7d4b6 | |||
e251711b4a | |||
a43db43f42 | |||
72c48e98c3 | |||
14d3b6fa45 | |||
05ce4da8c5 | |||
ea3c0ae576 | |||
95363f82ea | |||
4603e2dc8b | |||
23e8c5c683 | |||
46c91cfbff | |||
4d148cc57d | |||
f1a692f6c5 | |||
2889569238 | |||
0b02a71a1a | |||
d9781b6396 | |||
0df30c74c9 | |||
59d0f5eae6 | |||
57cc2bc1fa | |||
ce775e03ab | |||
3a0426ae6d | |||
c972df0656 | |||
5dbf1421f0 | |||
9b01381af1 | |||
deac5ec94d | |||
07574e98a6 | |||
23b8c3ad8a | |||
30c316a335 | |||
9a1ffb3c77 | |||
1ddaf1d405 | |||
35ad3086ba | |||
ee509a0754 | |||
1576b23215 | |||
0880d27aea | |||
adc80d4cb0 | |||
269f3fe703 | |||
66b7461266 | |||
65ca1c32ff | |||
26b27129fd | |||
8525445e18 | |||
954f696044 | |||
181bbc834a | |||
e2bce6fd38 | |||
42cae241f2 | |||
140adb0051 | |||
0fc8f68c79 | |||
795f92fe61 |
182
package-lock.json
generated
@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
"name": "itguild.info",
|
||||||
|
=======
|
||||||
"name": "outstaffing-react",
|
"name": "outstaffing-react",
|
||||||
|
>>>>>>> 42b597d58589cfa47890a35c06fd651fc654742a
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
@ -9,7 +13,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ckeditor/ckeditor5-build-classic": "^38.0.1",
|
"@ckeditor/ckeditor5-build-classic": "^38.0.1",
|
||||||
"@ckeditor/ckeditor5-react": "^6.0.0",
|
"@ckeditor/ckeditor5-react": "^6.0.0",
|
||||||
|
"@emotion/react": "^11.11.4",
|
||||||
"@reduxjs/toolkit": "^1.6.0",
|
"@reduxjs/toolkit": "^1.6.0",
|
||||||
|
"@table-library/react-table-library": "^4.1.7",
|
||||||
"@testing-library/jest-dom": "^5.12.0",
|
"@testing-library/jest-dom": "^5.12.0",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@testing-library/user-event": "^12.8.3",
|
"@testing-library/user-event": "^12.8.3",
|
||||||
@ -2830,21 +2836,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/babel-plugin": {
|
"node_modules/@emotion/babel-plugin": {
|
||||||
"version": "11.10.6",
|
"version": "11.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
|
||||||
"integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==",
|
"integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-module-imports": "^7.16.7",
|
"@babel/helper-module-imports": "^7.16.7",
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
"@emotion/hash": "^0.9.0",
|
"@emotion/hash": "^0.9.1",
|
||||||
"@emotion/memoize": "^0.8.0",
|
"@emotion/memoize": "^0.8.1",
|
||||||
"@emotion/serialize": "^1.1.1",
|
"@emotion/serialize": "^1.1.2",
|
||||||
"babel-plugin-macros": "^3.1.0",
|
"babel-plugin-macros": "^3.1.0",
|
||||||
"convert-source-map": "^1.5.0",
|
"convert-source-map": "^1.5.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"find-root": "^1.1.0",
|
"find-root": "^1.1.0",
|
||||||
"source-map": "^0.5.7",
|
"source-map": "^0.5.7",
|
||||||
"stylis": "4.1.3"
|
"stylis": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
|
"node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
|
||||||
@ -2867,39 +2873,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/cache": {
|
"node_modules/@emotion/cache": {
|
||||||
"version": "11.10.5",
|
"version": "11.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
|
||||||
"integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==",
|
"integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/memoize": "^0.8.0",
|
"@emotion/memoize": "^0.8.1",
|
||||||
"@emotion/sheet": "^1.2.1",
|
"@emotion/sheet": "^1.2.2",
|
||||||
"@emotion/utils": "^1.2.0",
|
"@emotion/utils": "^1.2.1",
|
||||||
"@emotion/weak-memoize": "^0.3.0",
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
"stylis": "4.1.3"
|
"stylis": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/hash": {
|
"node_modules/@emotion/hash": {
|
||||||
"version": "0.9.0",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
|
||||||
"integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ=="
|
"integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/memoize": {
|
"node_modules/@emotion/memoize": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
|
||||||
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA=="
|
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/react": {
|
"node_modules/@emotion/react": {
|
||||||
"version": "11.10.6",
|
"version": "11.11.4",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
|
||||||
"integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==",
|
"integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
"@emotion/babel-plugin": "^11.10.6",
|
"@emotion/babel-plugin": "^11.11.0",
|
||||||
"@emotion/cache": "^11.10.5",
|
"@emotion/cache": "^11.11.0",
|
||||||
"@emotion/serialize": "^1.1.1",
|
"@emotion/serialize": "^1.1.3",
|
||||||
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.0",
|
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
|
||||||
"@emotion/utils": "^1.2.0",
|
"@emotion/utils": "^1.2.1",
|
||||||
"@emotion/weak-memoize": "^0.3.0",
|
"@emotion/weak-memoize": "^0.3.1",
|
||||||
"hoist-non-react-statics": "^3.3.1"
|
"hoist-non-react-statics": "^3.3.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@ -2912,44 +2918,44 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/serialize": {
|
"node_modules/@emotion/serialize": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz",
|
||||||
"integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==",
|
"integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/hash": "^0.9.0",
|
"@emotion/hash": "^0.9.1",
|
||||||
"@emotion/memoize": "^0.8.0",
|
"@emotion/memoize": "^0.8.1",
|
||||||
"@emotion/unitless": "^0.8.0",
|
"@emotion/unitless": "^0.8.1",
|
||||||
"@emotion/utils": "^1.2.0",
|
"@emotion/utils": "^1.2.1",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/sheet": {
|
"node_modules/@emotion/sheet": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
|
||||||
"integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA=="
|
"integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/unitless": {
|
"node_modules/@emotion/unitless": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||||
"integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw=="
|
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz",
|
||||||
"integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
|
"integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.8.0"
|
"react": ">=16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/utils": {
|
"node_modules/@emotion/utils": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
|
||||||
"integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw=="
|
"integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
|
||||||
},
|
},
|
||||||
"node_modules/@emotion/weak-memoize": {
|
"node_modules/@emotion/weak-memoize": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
|
||||||
"integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
|
"integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.0",
|
||||||
@ -5203,6 +5209,21 @@
|
|||||||
"url": "https://github.com/sponsors/gregberge"
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@table-library/react-table-library": {
|
||||||
|
"version": "4.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@table-library/react-table-library/-/react-table-library-4.1.7.tgz",
|
||||||
|
"integrity": "sha512-KKFjdACvEUeD9yhgXBjZUJSdE9pxUbJdou4Pp71FW8dxQWc7LcMcSxpveSfGXw8KlcWY0hThJOwyjQb+UKOmnw==",
|
||||||
|
"dependencies": {
|
||||||
|
"clsx": "1.1.1",
|
||||||
|
"react-virtualized-auto-sizer": "1.0.7",
|
||||||
|
"react-window": "1.8.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emotion/react": ">= 11",
|
||||||
|
"react": ">=16.8.0",
|
||||||
|
"react-dom": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@testing-library/jest-dom": {
|
"node_modules/@testing-library/jest-dom": {
|
||||||
"version": "5.16.5",
|
"version": "5.16.5",
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz",
|
||||||
@ -8011,9 +8032,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001458",
|
"version": "1.0.30001597",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
|
||||||
"integrity": "sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==",
|
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -8022,6 +8043,10 @@
|
|||||||
{
|
{
|
||||||
"type": "tidelift",
|
"type": "tidelift",
|
||||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -8247,6 +8272,14 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/clsx": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/co": {
|
"node_modules/co": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||||
@ -21332,6 +21365,39 @@
|
|||||||
"react-dom": ">=16.6.0"
|
"react-dom": ">=16.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-virtualized-auto-sizer": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc",
|
||||||
|
"react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-window": {
|
||||||
|
"version": "1.8.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.7.tgz",
|
||||||
|
"integrity": "sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.0.0",
|
||||||
|
"memoize-one": ">=3.1.1 <6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">8.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-window/node_modules/memoize-one": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
|
||||||
|
},
|
||||||
"node_modules/react-yandex-metrika": {
|
"node_modules/react-yandex-metrika": {
|
||||||
"version": "2.6.0",
|
"version": "2.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-yandex-metrika/-/react-yandex-metrika-2.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-yandex-metrika/-/react-yandex-metrika-2.6.0.tgz",
|
||||||
@ -23086,9 +23152,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/stylis": {
|
"node_modules/stylis": {
|
||||||
"version": "4.1.3",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
|
||||||
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
|
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
|
||||||
},
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ckeditor/ckeditor5-build-classic": "^38.0.1",
|
"@ckeditor/ckeditor5-build-classic": "^38.0.1",
|
||||||
"@ckeditor/ckeditor5-react": "^6.0.0",
|
"@ckeditor/ckeditor5-react": "^6.0.0",
|
||||||
|
"@emotion/react": "^11.11.4",
|
||||||
"@reduxjs/toolkit": "^1.6.0",
|
"@reduxjs/toolkit": "^1.6.0",
|
||||||
|
"@table-library/react-table-library": "^4.1.7",
|
||||||
"@testing-library/jest-dom": "^5.12.0",
|
"@testing-library/jest-dom": "^5.12.0",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@testing-library/user-event": "^12.8.3",
|
"@testing-library/user-event": "^12.8.3",
|
||||||
|
157
src/App.js
@ -1,157 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import {
|
|
||||||
BrowserRouter as Router,
|
|
||||||
Route,
|
|
||||||
Routes,
|
|
||||||
Navigate,
|
|
||||||
} from "react-router-dom";
|
|
||||||
|
|
||||||
import { getNotification } from "@redux/outstaffingSlice";
|
|
||||||
|
|
||||||
import Auth from "./pages/Auth/Auth";
|
|
||||||
import CatalogSpecialists from "@pages/CatalogSpecialists/CatalogSpecialists";
|
|
||||||
import { TrackerIntro } from "@pages/TrackerIntro/TrackerIntro"
|
|
||||||
import { CompanyInfo } from "@pages/CompanyInfo/CompanyInfo";
|
|
||||||
import { TrackerAuth } from "@pages/TrackerAuth/TrackerAuth";
|
|
||||||
import { TrackerRegistration } from "@pages/TrackerRegistration/TrackerRegistration";
|
|
||||||
import Home from "./pages/Home/Home";
|
|
||||||
import Candidate from "./components/Candidate/Candidate";
|
|
||||||
import Calendar from "./components/Calendar/Calendar";
|
|
||||||
import ReportForm from "./components/ReportForm/ReportForm";
|
|
||||||
import FreeDevelopers from "./components/FreeDevelopers/FreeDevelopers";
|
|
||||||
import { TicketFullScreen } from "@components/Modal/Tracker/TicketFullScreen/TicketFullScreen";
|
|
||||||
import { ProfileCalendar } from "@components/ProfileCalendar/ProfileCalendar";
|
|
||||||
import { RegistrationSetting } from "@pages/RegistrationSetting/RegistrationSetting";
|
|
||||||
import Article from "./pages/Article/Article";
|
|
||||||
import FormPage from "./pages/FormPage/FormPage";
|
|
||||||
import SingleReportPage from "./pages/SingleReportPage/SingleReportPage";
|
|
||||||
import { QuizPage } from "@pages/Quiz/QuizPage";
|
|
||||||
import { QuizReportPage } from "@pages/Quiz/QuizReportPage";
|
|
||||||
import { Profile } from "@pages/Profile/Profile";
|
|
||||||
import { Summary } from "@pages/Summary/Summary";
|
|
||||||
import { ViewReport } from "@pages/ViewReport/ViewReport";
|
|
||||||
import { Tracker } from "@pages/Tracker/Tracker";
|
|
||||||
import { Payouts } from "@pages/Payouts/Payouts";
|
|
||||||
import { PartnerSettings } from "@pages/PartnerSettings/PartnerSettings";
|
|
||||||
import { PartnerRequests } from "@pages/PartnerRequests/PartnerRequests";
|
|
||||||
import { PartnerAddRequest } from "@pages/PartnerAddRequest/PartnerAddRequest";
|
|
||||||
import { PartnerBid } from "@pages/PartnerBid/PartnerBid";
|
|
||||||
import { PartnerCategories } from "@pages/PartnerСategories/PartnerСategories";
|
|
||||||
import { PartnerTreaties } from "@pages/PartnerTreaties/PartnerTreaties";
|
|
||||||
import { PartnerEmployees } from "@pages/PartnerEmployees/PartnerEmployees";
|
|
||||||
import { AuthForCandidate } from "@pages/AuthForCandidate/AuthForCandidate";
|
|
||||||
import { RegistrationForCandidate } from "@pages/RegistrationForCandidate/RegistrationForCandidate";
|
|
||||||
import { ProfileCandidate } from "@pages/ProfileCandidate/ProfileCandidate";
|
|
||||||
import { PartnerEmployeeReport } from "@pages/PartnerEmployeeReport/PartnerEmployeeReport";
|
|
||||||
import { PassingTests } from "@pages/Quiz/PassingTests";
|
|
||||||
import Blog from "./pages/Blog/Blog";
|
|
||||||
import Statistics from "@pages/Statistics/Statistics";
|
|
||||||
import { ProjectTracker } from "@pages/ProjectTracker/ProjectTracker";
|
|
||||||
import { FrequentlyAskedQuestions } from "@pages/FrequentlyAskedQuestions/FrequentlyAskedQuestions";
|
|
||||||
import { FrequentlyAskedQuestion } from "@pages/FrequentlyAskedQuestion/FrequentlyAskedQuestion";
|
|
||||||
import Notification from "@components/Notification/Notification";
|
|
||||||
import { useSelector } from "react-redux";
|
|
||||||
|
|
||||||
import "./assets/global.scss";
|
|
||||||
import "./assets/fonts/stylesheet.css";
|
|
||||||
import "bootstrap/dist/css/bootstrap.min.css";
|
|
||||||
|
|
||||||
const App = () => {
|
|
||||||
const notification = useSelector(getNotification)
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Router>
|
|
||||||
<Routes>
|
|
||||||
<Route exact path="/auth" element={<Auth />} />
|
|
||||||
<Route exact path="/tracker-intro" element={<TrackerIntro />} />
|
|
||||||
<Route exact path="/tracker-auth" element={<TrackerAuth />} />
|
|
||||||
<Route exact path="/tracker-registration" element={<TrackerRegistration />} />
|
|
||||||
<Route exact path="/company" element={<CompanyInfo />} />
|
|
||||||
<Route exact path="/registration-setting" element={<RegistrationSetting />} />
|
|
||||||
<Route exact path="/catalog-specialists" element={<CatalogSpecialists />} />
|
|
||||||
|
|
||||||
<Route exact path="/worker/:id" element={<FreeDevelopers />} />
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/tracker/task/:id"
|
|
||||||
element={<TicketFullScreen />}
|
|
||||||
></Route>
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/tracker/project/:id"
|
|
||||||
element={<ProjectTracker />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route exact path="/auth-candidate" element={<AuthForCandidate />} />
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/registration-candidate"
|
|
||||||
element={<RegistrationForCandidate />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route exact path="/blog" element={<Blog />}></Route>
|
|
||||||
<Route exact path="/blog/article/:id" element={<Article />}></Route>
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/frequently-asked-questions"
|
|
||||||
element={<FrequentlyAskedQuestions />}
|
|
||||||
/>
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/frequently-asked-question/:id"
|
|
||||||
element={<FrequentlyAskedQuestion />}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Route exact path="/candidate/:id" element={<Candidate />} />
|
|
||||||
<Route exact path="/candidate/:id/form" element={<FormPage />} />
|
|
||||||
<Route path="/:userId/calendar" element={<Calendar />} />
|
|
||||||
|
|
||||||
<Route path="/report/:id" element={<SingleReportPage />} />
|
|
||||||
|
|
||||||
<Route exact path="profile">
|
|
||||||
<Route index element={<Profile />} />
|
|
||||||
<Route exact path="catalog" element={<Home />} />
|
|
||||||
<Route exact path="calendar" element={<ProfileCalendar />} />
|
|
||||||
<Route exact path="calendar/report" element={<ReportForm />} />
|
|
||||||
<Route exact path="calendar/view/:date/:id" element={<ViewReport />} />
|
|
||||||
<Route exact path="summary" element={<Summary />} />
|
|
||||||
<Route exact path="tracker" element={<Tracker />} />
|
|
||||||
<Route exact path="statistics/:id" element={<Statistics/>}/>
|
|
||||||
<Route exact path="payouts" element={<Payouts />} />
|
|
||||||
<Route exact path="settings" element={<PartnerSettings />} />
|
|
||||||
<Route exact path="requests" element={<PartnerRequests />} />
|
|
||||||
<Route exact path="requests-add" element={<PartnerAddRequest />} />
|
|
||||||
<Route exact path="requests-edit" element={<PartnerAddRequest />} />
|
|
||||||
<Route exact path="requests-bid" element={<PartnerBid />} />
|
|
||||||
<Route exact path="employees" element={<PartnerCategories />} />
|
|
||||||
<Route exact path="employees/report/:uuid" element={<PartnerEmployeeReport />} />
|
|
||||||
<Route exact path="treaties" element={<PartnerTreaties />} />
|
|
||||||
<Route exact path="quiz">
|
|
||||||
<Route index element={<QuizPage />} />
|
|
||||||
<Route exact path="test/:uuid" element={<PassingTests />} />
|
|
||||||
<Route exact path="report/:uuid" element={<QuizReportPage />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="categories/employees"
|
|
||||||
element={<PartnerEmployees />}
|
|
||||||
/>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
|
|
||||||
<Route exact path="profile-candidate/:id">
|
|
||||||
<Route index element={<ProfileCandidate />} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="*" element={<Navigate to="/auth" replace />} />
|
|
||||||
</Routes>
|
|
||||||
</Router>
|
|
||||||
{notification.show &&
|
|
||||||
<Notification />
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default App;
|
|
34
src/App.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import React from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import {
|
||||||
|
Navigate,
|
||||||
|
Route,
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Routes
|
||||||
|
} from "react-router-dom";
|
||||||
|
|
||||||
|
import { getNotification } from "@redux/outstaffingSlice";
|
||||||
|
|
||||||
|
import { MainPage } from "@pages/MainPage/MainPage";
|
||||||
|
|
||||||
|
import { Notification } from "@components/Notification/Notification";
|
||||||
|
|
||||||
|
import "assets/fonts/stylesheet.css";
|
||||||
|
import "assets/global.scss";
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const notification = useSelector(getNotification);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Router>
|
||||||
|
<Routes>
|
||||||
|
<Route path="*" element={<MainPage />} />
|
||||||
|
</Routes>
|
||||||
|
</Router>
|
||||||
|
{notification.show && <Notification />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default App;
|
@ -41,7 +41,7 @@ export const apiRequest = (
|
|||||||
if (response.data?.redirect || response.status === 401) {
|
if (response.data?.redirect || response.status === 401) {
|
||||||
window.location.replace("/auth");
|
window.location.replace("/auth");
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
// dispatch(auth(false));
|
store.dispatch(auth(false));
|
||||||
store.dispatch(setProfileInfo({}));
|
store.dispatch(setProfileInfo({}));
|
||||||
}
|
}
|
||||||
return resolve(response);
|
return resolve(response);
|
||||||
|
BIN
src/assets/fonts/GeraspohekoRegular.eot
Normal file
BIN
src/assets/fonts/GeraspohekoRegular.ttf
Normal file
BIN
src/assets/fonts/GeraspohekoRegular.woff
Normal file
BIN
src/assets/fonts/GeraspohekoRegular.woff2
Normal file
@ -394,3 +394,16 @@
|
|||||||
url('LabGrotesque-Light.ttf') format('truetype');
|
url('LabGrotesque-Light.ttf') format('truetype');
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Geraspoheko';
|
||||||
|
src: url('GeraspohekoRegular.eot');
|
||||||
|
src: local('Geraspoheko'), local('GeraspohekoRegular'),
|
||||||
|
url('GeraspohekoRegular.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('GeraspohekoRegular.woff2') format('woff2'),
|
||||||
|
url('GeraspohekoRegular.woff') format('woff'),
|
||||||
|
url('GeraspohekoRegular.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
BIN
src/assets/icons/arrows/arrowCalendar_left.png
Normal file
After Width: | Height: | Size: 229 B |
BIN
src/assets/icons/arrows/arrowCalendar_right.png
Normal file
After Width: | Height: | Size: 238 B |
10
src/assets/icons/arrows/arrowLanding.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="27" height="15" viewBox="0 0 27 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_76_12)">
|
||||||
|
<path d="M22.7685 8.75957H22.345C15.3781 8.75957 8.41109 8.75957 1.44414 8.75957C1.22469 8.76628 1.00541 8.7416 0.792717 8.68623C0.259454 8.5302 -0.0459255 8.00204 0.00624986 7.38338C0.0222895 7.10907 0.131776 6.84899 0.315899 6.64783C0.500021 6.44667 0.747298 6.31697 1.01524 6.28102C1.18606 6.26022 1.35806 6.2511 1.53009 6.25372C8.46839 6.25372 15.407 6.25372 22.3458 6.25372H22.7931C22.6734 6.12655 22.6066 6.05322 22.5376 5.98222C21.3043 4.73398 20.0705 3.48392 18.8362 2.23203C18.4764 1.86848 18.2991 1.45188 18.438 0.941657C18.4905 0.730456 18.5968 0.537048 18.7462 0.38089C18.8956 0.224732 19.0828 0.111333 19.289 0.052101C19.4952 -0.00713091 19.7131 -0.0101062 19.9208 0.043474C20.1284 0.0970542 20.3186 0.205301 20.472 0.357322C20.9393 0.80435 21.3828 1.27556 21.8355 1.73663C23.3982 3.32762 24.9604 4.9181 26.5221 6.50805C27.1582 7.15557 27.1597 7.85069 26.5275 8.4951C24.5402 10.5235 22.5445 12.5363 20.568 14.5725C19.717 15.4494 18.6574 14.8432 18.4418 14.0724C18.377 13.8673 18.3702 13.6478 18.4221 13.439C18.4741 13.2301 18.5827 13.0403 18.7357 12.8913C19.0672 12.541 19.4086 12.2 19.747 11.856L22.5092 9.04745C22.5798 8.96787 22.6465 8.88985 22.7685 8.75957Z" fill="#A7CA60"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_76_12">
|
||||||
|
<rect width="27" height="15" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/icons/arrows/arrowReviewsLeft.png
Normal file
After Width: | Height: | Size: 298 B |
BIN
src/assets/icons/arrows/arrowReviewsRight.png
Normal file
After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
3
src/assets/icons/arrows/tableArrow.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg width="9" height="6" viewBox="0 0 9 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.11629 5.8584L8.07227 0.858398H0.160323L4.11629 5.8584Z" fill="#2E3A59"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 184 B |
11
src/assets/icons/authIcon.svg
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_68_166)">
|
||||||
|
<path d="M7.83533 -0.000427246C8.01139 0.0347969 8.19098 0.0603351 8.36352 0.106127C10.1325 0.574608 11.2721 1.69782 11.6378 3.48501C12.1598 6.0326 10.4182 8.17423 8.22135 8.59868C7.24129 8.79102 6.22489 8.63913 5.34382 8.16864C4.46275 7.69816 3.771 6.93791 3.38538 6.0163C2.7159 4.41052 3.02929 2.48332 4.40345 1.19367C5.09537 0.544667 5.89733 0.14003 6.8441 0.0330362C6.87122 0.0255363 6.89714 0.014272 6.92113 -0.000427246H7.83533Z" fill="#838383"/>
|
||||||
|
<path d="M7.5037 17.9969C5.99838 17.9969 4.49305 18.0057 2.98817 17.993C2.33244 17.997 1.69302 17.7886 1.16549 17.399C0.50526 16.9094 0.11176 16.2485 0.0408957 15.4344C-0.0880693 13.9523 0.0822738 12.4997 0.633346 11.1106C0.967863 10.2674 1.46655 9.54135 2.29624 9.0962C2.79777 8.82462 3.36124 8.68806 3.93142 8.69993C4.11276 8.70345 4.30467 8.79195 4.47016 8.88178C4.7369 9.0262 4.98559 9.20408 5.24263 9.36611C6.01995 9.85749 6.86152 10.1243 7.78716 10.0547C8.46852 10.0037 9.09838 9.77647 9.67982 9.42071C9.87921 9.29874 10.0861 9.18338 10.2674 9.03764C10.7428 8.65414 11.2683 8.64798 11.8295 8.77346C12.8648 9.00374 13.5937 9.61928 14.0981 10.5311C14.6025 11.443 14.8301 12.4244 14.9273 13.4442C14.9789 13.9979 15.0026 14.5538 14.9982 15.1099C14.989 16.6108 13.8608 17.8252 12.3652 17.9648C12.1328 17.9863 11.8982 17.9987 11.6649 17.9991C10.2767 18.0026 8.88887 17.9991 7.50063 17.9991L7.5037 17.9969Z" fill="#838383"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_68_166">
|
||||||
|
<rect width="15" height="18" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg">
|
<path d="M14.569 2.26115H12.9023V1.42782C12.9023 1.2068 12.8145 0.99484 12.6583 0.83856C12.502 0.68228 12.29 0.594482 12.069 0.594482C11.848 0.594482 11.636 0.68228 11.4798 0.83856C11.3235 0.99484 11.2357 1.2068 11.2357 1.42782V2.26115H6.23568V1.42782C6.23568 1.2068 6.14788 0.99484 5.9916 0.83856C5.83532 0.68228 5.62336 0.594482 5.40234 0.594482C5.18133 0.594482 4.96937 0.68228 4.81309 0.83856C4.65681 0.99484 4.56901 1.2068 4.56901 1.42782V2.26115H2.90234C2.2393 2.26115 1.60342 2.52454 1.13458 2.99338C0.665736 3.46222 0.402344 4.09811 0.402344 4.76115V14.7611C0.402344 15.4242 0.665736 16.0601 1.13458 16.5289C1.60342 16.9978 2.2393 17.2612 2.90234 17.2612H14.569C15.2321 17.2612 15.8679 16.9978 16.3368 16.5289C16.8056 16.0601 17.069 15.4242 17.069 14.7611V4.76115C17.069 4.09811 16.8056 3.46222 16.3368 2.99338C15.8679 2.52454 15.2321 2.26115 14.569 2.26115ZM15.4023 14.7611C15.4023 14.9822 15.3145 15.1941 15.1583 15.3504C15.002 15.5067 14.79 15.5945 14.569 15.5945H2.90234C2.68133 15.5945 2.46937 15.5067 2.31309 15.3504C2.15681 15.1941 2.06901 14.9822 2.06901 14.7611V8.92782H15.4023V14.7611ZM15.4023 7.26115H2.06901V4.76115C2.06901 4.54014 2.15681 4.32817 2.31309 4.17189C2.46937 4.01561 2.68133 3.92782 2.90234 3.92782H4.56901V4.76115C4.56901 4.98216 4.65681 5.19412 4.81309 5.3504C4.96937 5.50669 5.18133 5.59448 5.40234 5.59448C5.62336 5.59448 5.83532 5.50669 5.9916 5.3504C6.14788 5.19412 6.23568 4.98216 6.23568 4.76115V3.92782H11.2357V4.76115C11.2357 4.98216 11.3235 5.19412 11.4798 5.3504C11.636 5.50669 11.848 5.59448 12.069 5.59448C12.29 5.59448 12.502 5.50669 12.6583 5.3504C12.8145 5.19412 12.9023 4.98216 12.9023 4.76115V3.92782H14.569C14.79 3.92782 15.002 4.01561 15.1583 4.17189C15.3145 4.32817 15.4023 4.54014 15.4023 4.76115V7.26115Z" fill="#406128"/>
|
||||||
<path d="M1411.824 0c31.17 0 56.47 25.3 56.47 56.471v56.47h169.412c93.403 0 169.412 76.01 169.412 169.412V1920H113V282.353c0-93.402 76.009-169.412 169.412-169.412h169.41v-56.47c0-31.172 25.3-56.47 56.472-56.47s56.47 25.298 56.47 56.47v56.47h790.589v-56.47c0-31.172 25.299-56.47 56.47-56.47Zm282.352 564.705H225.942v1242.353h1468.234V564.705Zm-1016.47 677.648v338.824H338.882v-338.824h338.824Zm451.765 0v338.824H790.647v-338.824h338.824Zm451.764 0v338.824h-338.823v-338.824h338.823Zm-1016.47 112.941H451.824v112.941h112.941v-112.941Zm451.764 0H903.588v112.941h112.941v-112.941Zm451.765 0h-112.941v112.941h112.941v-112.941ZM677.706 790.588v338.824H338.882V790.588h338.824Zm451.765 0v338.824H790.647V790.588h338.824Zm451.764 0v338.824h-338.823V790.588h338.823ZM564.765 903.53H451.824v112.941h112.941V903.53Zm451.764 0H903.588v112.941h112.941V903.53Zm451.765 0h-112.941v112.941h112.941V903.53ZM451.823 225.882H282.412c-31.06 0-56.47 25.3-56.47 56.471v169.412h1468.234V282.353c0-31.172-25.411-56.47-56.47-56.47h-169.412v56.47c0 31.172-25.3 56.471-56.47 56.471-31.172 0-56.471-25.299-56.471-56.47v-56.472H564.765v56.471c0 31.172-25.3 56.471-56.471 56.471-31.171 0-56.471-25.299-56.471-56.47v-56.472Z" fill-rule="evenodd"/>
|
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/icons/financeIcon.png
Normal file
After Width: | Height: | Size: 726 B |
9
src/assets/icons/landingClue.svg
Normal file
After Width: | Height: | Size: 1.1 MiB |
15
src/assets/icons/telegramIcon.svg
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<svg width="23" height="22" viewBox="0 0 23 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_64_66)">
|
||||||
|
<mask id="mask0_64_66" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="23" height="22">
|
||||||
|
<path d="M22.0015 0H0V22H22.0015V0Z" fill="white"/>
|
||||||
|
</mask>
|
||||||
|
<g mask="url(#mask0_64_66)">
|
||||||
|
<path d="M10.9461 22.0001C4.87347 21.9702 -0.0423218 16.9977 0.000274756 10.9273C0.0436186 4.86661 4.99678 -0.0297562 11.0545 0.000136144C17.1159 0.0307758 22.0317 4.98468 22.0018 11.0349C21.9719 17.1247 17.0255 22.0293 10.9461 22.0001ZM16.0487 7.6025C16.0711 6.87985 15.8103 6.63324 15.2715 6.68256C14.9591 6.71096 14.664 6.8126 14.3777 6.93217C12.3622 7.77513 10.3475 8.61809 8.335 9.46778C7.12361 9.97969 5.91447 10.4968 4.71056 11.0259C4.48935 11.1231 4.25096 11.2531 4.27338 11.567C4.2958 11.8749 4.56782 11.9234 4.77557 11.9937C5.37491 12.1962 5.97874 12.392 6.59303 12.5415C7.0997 12.6655 7.61161 12.6199 8.06298 12.3173C9.56955 11.3069 11.0709 10.2898 12.5782 9.28021C12.7307 9.17857 12.9108 8.94392 13.0901 9.15316C13.2747 9.36764 13.0087 9.5029 12.8801 9.62995C11.8354 10.6612 10.7809 11.6828 9.7362 12.7133C9.26839 13.1752 9.31397 13.6011 9.85727 13.9718C10.1547 14.1743 10.4603 14.3656 10.76 14.5667C11.5544 15.0995 12.3361 15.6525 13.1447 16.1629C14.0243 16.7182 14.4457 16.5523 14.7476 15.5852C14.7768 15.4911 14.8029 15.3947 14.8239 15.2983C15.1318 13.9016 15.3246 12.4847 15.5465 11.073C15.7378 9.85713 15.8993 8.63678 16.0472 7.6025H16.0487Z" fill="#9F9F9F"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_64_66">
|
||||||
|
<rect width="23" height="22" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
16
src/assets/icons/vkIcon.svg
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_64_59)">
|
||||||
|
<mask id="mask0_64_59" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="22" height="22">
|
||||||
|
<path d="M21.9955 0H0V22H21.9955V0Z" fill="white"/>
|
||||||
|
</mask>
|
||||||
|
<g mask="url(#mask0_64_59)">
|
||||||
|
<path d="M10.9755 22C4.9123 21.9881 -0.0230861 17.0228 8.12304e-05 10.9589C0.0232485 4.91 4.97209 -0.0119356 11.0195 2.17408e-05C17.07 0.0119791 21.9994 4.95335 21.9956 11.003C21.9919 17.0743 17.0438 22.012 10.9755 22ZM11.4724 9.84166C11.4724 9.53076 11.4807 9.21913 11.4702 8.90824C11.4545 8.42621 11.3454 8.29393 10.8716 8.20798C10.2289 8.09215 9.58239 8.10336 8.93968 8.20873C8.77303 8.23638 8.60861 8.31336 8.4569 8.39332C8.28875 8.48151 8.26708 8.58987 8.47858 8.66012C8.78797 8.76325 8.99424 8.96653 9.04132 9.29162C9.12203 9.84689 9.16313 10.4044 9.05552 10.9634C8.95164 11.503 8.5974 11.6315 8.1774 11.2691C8.07502 11.1801 7.98758 11.0718 7.90014 10.9671C7.31797 10.2669 6.96373 9.44856 6.68348 8.59436C6.58409 8.29019 6.37633 8.13923 6.07739 8.134C5.45561 8.12279 4.83308 8.12129 4.2113 8.13998C3.84959 8.15119 3.76739 8.28645 3.91685 8.62126C4.63728 10.2355 5.43095 11.8101 6.52953 13.2084C7.66324 14.6515 9.10634 15.4354 10.9874 15.2972C11.314 15.2733 11.515 15.2045 11.4702 14.8226C11.4538 14.6784 11.4821 14.5237 11.5158 14.3795C11.6234 13.9139 11.9208 13.7756 12.3491 13.9841C12.6428 14.1276 12.8931 14.3376 13.127 14.5581C13.6898 15.0909 14.3302 15.3689 15.1202 15.2987C15.5155 15.2636 15.9161 15.2927 16.3144 15.292C16.6387 15.292 17.0117 15.3241 17.1589 14.9684C17.3001 14.6261 17.0109 14.3854 16.7957 14.1702C16.3024 13.6792 15.7838 13.2136 15.2868 12.7256C14.9468 12.3916 14.9274 12.1935 15.2046 11.8116C15.4819 11.4297 15.789 11.0688 16.0768 10.6944C16.5401 10.0913 16.9661 9.465 17.1634 8.71617C17.2785 8.27898 17.2037 8.15567 16.7576 8.14521C15.999 8.12802 15.2397 8.14297 14.4812 8.15119C14.2189 8.15418 14.0874 8.32307 14.0066 8.554C13.8788 8.91646 13.757 9.28265 13.6038 9.63464C13.334 10.2557 12.9701 10.8192 12.4634 11.2758C12.2885 11.4335 12.0793 11.5874 11.8252 11.4963C11.5509 11.3984 11.4919 11.1368 11.4784 10.8849C11.4597 10.5374 11.4739 10.1884 11.4724 9.84016V9.84166Z" fill="#9F9F9F"/>
|
||||||
|
<path d="M11.4733 9.84153C11.4733 10.1898 11.4598 10.5388 11.4785 10.8863C11.492 11.1381 11.5518 11.3997 11.8253 11.4976C12.0794 11.588 12.2894 11.4341 12.4635 11.2772C12.9702 10.8205 13.3334 10.257 13.6039 9.63601C13.7571 9.28402 13.879 8.91782 14.0067 8.55537C14.0882 8.32369 14.219 8.15479 14.4813 8.15255C15.2398 8.14433 15.9991 8.13013 16.7577 8.14657C17.2038 8.15629 17.2793 8.2796 17.1635 8.71754C16.9662 9.46636 16.5402 10.0926 16.0769 10.6957C15.7891 11.0701 15.482 11.4311 15.2047 11.813C14.9275 12.1956 14.9461 12.3929 15.2869 12.727C15.7839 13.215 16.3026 13.6806 16.7958 14.1716C17.011 14.3861 17.3002 14.6267 17.159 14.9697C17.0125 15.3255 16.6396 15.2933 16.3145 15.2933C15.9162 15.2933 15.5156 15.2649 15.1203 15.3C14.3303 15.3703 13.6906 15.0923 13.1271 14.5594C12.894 14.3382 12.6436 14.129 12.3492 13.9855C11.9209 13.7762 11.6235 13.9152 11.5159 14.3808C11.4823 14.5251 11.4539 14.6798 11.4703 14.824C11.5144 15.2059 11.3141 15.2746 10.9875 15.2986C9.10646 15.4368 7.66337 14.6529 6.52967 13.2098C5.43109 11.8115 4.63817 10.2369 3.91699 8.62262C3.76752 8.28782 3.84973 8.15255 4.21144 8.14134C4.83321 8.12266 5.45575 8.12415 6.07753 8.13536C6.37721 8.1406 6.58422 8.29156 6.68362 8.59572C6.96312 9.44992 7.3181 10.2683 7.90028 10.9685C7.98772 11.0739 8.07441 11.1822 8.17754 11.2704C8.59679 11.6329 8.95178 11.5051 9.05566 10.9648C9.16327 10.4058 9.12217 9.84825 9.04146 9.29298C8.99437 8.96715 8.78811 8.76387 8.47871 8.66149C8.26647 8.59124 8.28889 8.48287 8.45704 8.39469C8.60875 8.31472 8.77315 8.237 8.93981 8.2101C9.58177 8.10472 10.229 8.09351 10.8717 8.20935C11.3455 8.29455 11.4546 8.42682 11.4703 8.9096C11.48 9.22049 11.4725 9.53213 11.4725 9.84302L11.4733 9.84153Z" fill="#FBFBFB"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_64_59">
|
||||||
|
<rect width="22" height="22" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.0 KiB |
12
src/assets/images/EllipseIntro.svg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<svg width="1005" height="969" viewBox="0 0 1005 969" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_f_53_13)">
|
||||||
|
<circle cx="502.5" cy="466.5" r="281.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_f_53_13" x="0.300003" y="-35.7" width="1004.4" height="1004.4" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feGaussianBlur stdDeviation="110.35" result="effect1_foregroundBlur_53_13"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 596 B |
BIN
src/assets/images/backgroundLandingIntro.png
Normal file
After Width: | Height: | Size: 40 KiB |
11
src/assets/images/backgroundLandingIntro.svg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/images/backgroundOpportunity.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/images/cat.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
src/assets/images/clue.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
src/assets/images/landingBackgroundCode.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
11
src/assets/images/landingBackgroundCode.svg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/images/landingBackgroundCode1.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
src/assets/images/landingCat.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
src/assets/images/reviewsImgMok.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/stackProjectsFlag.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/images/stackProjectsFly.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
src/assets/images/stackProjectsHand.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/images/stackProjectsRabota.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/images/stackSteptsPortfolio.png
Normal file
After Width: | Height: | Size: 24 KiB |
@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { getCorrectDate } from "@components/Calendar/calendarHelper";
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
|
|
||||||
import "./archiveTasksItem.scss";
|
import "./archiveTasksItem.scss";
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ export const AuthBlock = ({ title, description, img, resetModal }) => {
|
|||||||
>
|
>
|
||||||
{isLoading ? <Loader /> : "Войти"}
|
{isLoading ? <Loader /> : "Войти"}
|
||||||
</button>
|
</button>
|
||||||
<NavLink to="/tracker-registration" className="auth__registration">
|
<NavLink to="/auth" className="auth__registration">
|
||||||
Регистрация
|
Регистрация
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
@ -70,6 +70,7 @@ export const AuthBox = ({ title }) => {
|
|||||||
dispatch(setUserInfo(res));
|
dispatch(setUserInfo(res));
|
||||||
dispatch(loading(false));
|
dispatch(loading(false));
|
||||||
dispatch(setRole("ROLE_PARTNER"));
|
dispatch(setRole("ROLE_PARTNER"));
|
||||||
|
navigate("/profile");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ import { LogoutButton } from "@components/LogoutButton/LogoutButton";
|
|||||||
|
|
||||||
import rectangle from "assets/images/rectangle_secondPage.png";
|
import rectangle from "assets/images/rectangle_secondPage.png";
|
||||||
|
|
||||||
|
import { currentMonth } from "../../utils/calendarHelper";
|
||||||
import CalendarComponent from "./CalendarComponent";
|
import CalendarComponent from "./CalendarComponent";
|
||||||
import "./calendar.scss";
|
import "./calendar.scss";
|
||||||
import { currentMonth } from "./calendarHelper";
|
|
||||||
|
|
||||||
const Calendar = () => {
|
export const Calendar = () => {
|
||||||
if (localStorage.getItem("role_status") !== "18") {
|
if (localStorage.getItem("role_status") !== "18") {
|
||||||
return <Navigate to="/profile" replace />;
|
return <Navigate to="/profile" replace />;
|
||||||
}
|
}
|
||||||
@ -84,5 +84,3 @@ const Calendar = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Calendar;
|
|
||||||
|
@ -6,8 +6,8 @@ import calendarIcon from "assets/icons/calendar.svg";
|
|||||||
import ellipse from "assets/icons/ellipse.png";
|
import ellipse from "assets/icons/ellipse.png";
|
||||||
import rectangle from "assets/images/rectangle__calendar.png";
|
import rectangle from "assets/images/rectangle__calendar.png";
|
||||||
|
|
||||||
|
import { calendarHelper, currentMonthAndDay } from "../../utils/calendarHelper";
|
||||||
import "./calendarComponent.scss";
|
import "./calendarComponent.scss";
|
||||||
import { calendarHelper, currentMonthAndDay } from "./calendarHelper";
|
|
||||||
|
|
||||||
const CalendarComponent = ({ onSelect }) => {
|
const CalendarComponent = ({ onSelect }) => {
|
||||||
const [value, setValue] = useState(moment());
|
const [value, setValue] = useState(moment());
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
.calendar {
|
.calendar {
|
||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
padding: 20px 30px;
|
padding: 20px 30px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -24,10 +23,14 @@
|
|||||||
|
|
||||||
.calendar__hours {
|
.calendar__hours {
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
line-height: 0;
|
font-size: 22px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
span {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,21 +58,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-box {
|
&-box {
|
||||||
|
background-color: #e5f1fb;
|
||||||
|
height: 47px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: 20px;
|
margin: 0 15px;
|
||||||
cursor: pointer;
|
padding: 0 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #406128;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
margin: 0px 10px;
|
width: 17px;
|
||||||
width: 12px;
|
height: 17px;
|
||||||
height: 12px;
|
margin: 0 10px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:first-child {
|
&-arrow {
|
||||||
transform: rotate(180deg);
|
display: flex;
|
||||||
margin: 0;
|
align-items: center;
|
||||||
}
|
cursor: pointer;
|
||||||
}
|
height: 47px;
|
||||||
|
padding: 0 8px;
|
||||||
|
background-color: #e5f1fb;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #18586e;
|
color: #18586e;
|
||||||
@ -108,12 +123,9 @@
|
|||||||
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: #398208;
|
color: #9babc5;
|
||||||
font-size: 25px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 500;
|
||||||
font-style: normal;
|
|
||||||
letter-spacing: normal;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,24 +140,48 @@
|
|||||||
|
|
||||||
button {
|
button {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 125px;
|
width: 135px;
|
||||||
height: 42px;
|
height: 82px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
box-shadow: 0 0 59px rgba(44, 44, 44, 0.05);
|
box-shadow: 0 0 59px rgba(44, 44, 44, 0.05);
|
||||||
border-radius: 5px;
|
border-radius: 10px;
|
||||||
border: 1px solid #c4c4c4;
|
border: 1px solid #c4c4c4;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
.form-date {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px 0 0 15px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-bottom-left-radius: 10px;
|
||||||
|
border-bottom-right-radius: 10px;
|
||||||
|
border-top: #eff5fa 2px solid;
|
||||||
|
|
||||||
|
.form-hours {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: black;
|
color: black;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 500;
|
font-weight: 400;
|
||||||
font-size: 12px;
|
font-size: 16px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
@media (max-width: 500px) {
|
@media (max-width: 500px) {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
@ -153,20 +189,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin: 0 5px 0 0;
|
|
||||||
|
|
||||||
@media (max-width: 968px) {
|
|
||||||
margin-right: 2px;
|
|
||||||
|
|
||||||
@media (max-width: 610px) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1200px) {
|
@media (max-width: 1200px) {
|
||||||
width: 110px;
|
width: 110px;
|
||||||
}
|
}
|
||||||
@ -215,17 +237,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.calendar__icon {
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-top: -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
|
||||||
.calendar__icon {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-days {
|
.select-days {
|
||||||
border-style: dashed !important;
|
border-style: dashed !important;
|
||||||
|
|
||||||
@ -247,11 +258,48 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.before {
|
.before {
|
||||||
background-color: #e5f9b6 !important;
|
background-color: #ffffff !important;
|
||||||
|
|
||||||
|
.form-date {
|
||||||
|
height: 35% !important;
|
||||||
|
}
|
||||||
|
.form-box {
|
||||||
|
background-color: #fafbfe;
|
||||||
|
|
||||||
|
.form-hours {
|
||||||
|
color: #6dd077;
|
||||||
|
background-color: #6dd0772f;
|
||||||
|
border-spacing: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex !important;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 95%;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 7px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #1458dd;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-hours::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
left: 0;
|
||||||
|
height: 75%;
|
||||||
|
border-left: 2px solid #6dd077;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pass {
|
.pass {
|
||||||
background-color: #f7d7c9 !important;
|
background-color: #ba5c33 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.today {
|
.today {
|
||||||
@ -260,7 +308,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.selected {
|
.selected {
|
||||||
background-color: #f9f9c3 !important;
|
background-color: #cbcbb4 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
@ -272,18 +320,25 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
column-gap: 16px;
|
column-gap: 16px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 500;
|
font-weight: 400;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.select {
|
.select {
|
||||||
|
background-color: #e5f1fb;
|
||||||
|
color: #406128;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: 2px solid #c4c4c4;
|
padding: 15px;
|
||||||
box-shadow: 0 0 59px rgba(44, 44, 44, 0.05);
|
|
||||||
padding: 5px 8px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
color: #6f6f6f;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 300;
|
||||||
|
margin: 0 0 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
|
@ -28,11 +28,11 @@ import rectangle from "assets/images/rectangle_secondPage.png";
|
|||||||
|
|
||||||
import "./candidate.scss";
|
import "./candidate.scss";
|
||||||
|
|
||||||
const Candidate = () => {
|
export const Candidate = () => {
|
||||||
if (localStorage.getItem("role_status") !== "18") {
|
if (localStorage.getItem("role_status") !== "18") {
|
||||||
return <Navigate to="/profile" replace />;
|
return <Navigate to="/profile" replace />;
|
||||||
}
|
}
|
||||||
// const { id: candidateId } = useParams();
|
const { id: candidateId } = useParams();
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ const Candidate = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiRequest(`/user/me`, {}).then((el) =>
|
apiRequest(`/resume?userId=${candidateId}`).then((el) =>
|
||||||
dispatch(currentCandidate(el.userCard))
|
dispatch(currentCandidate(el.userCard))
|
||||||
);
|
);
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
@ -91,10 +91,10 @@ const Candidate = () => {
|
|||||||
const { header, img, classes } = setStyles();
|
const { header, img, classes } = setStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="candidate__wrapper">
|
<div className="candidate">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<div className="container candidate">
|
<div className="container">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
{ name: "Главная", link: "/profile" },
|
{ name: "Главная", link: "/profile" },
|
||||||
@ -103,9 +103,7 @@ const Candidate = () => {
|
|||||||
link: "/profile/catalog"
|
link: "/profile/catalog"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: `${currentCandidateObj.specification} ${
|
name: `${currentCandidateObj.fio}`,
|
||||||
SKILLS[currentCandidateObj.position_id]
|
|
||||||
}, ${LEVELS[currentCandidateObj.level]}`,
|
|
||||||
link: `/candidate/${currentCandidateObj.id}`
|
link: `/candidate/${currentCandidateObj.id}`
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
@ -115,6 +113,7 @@ const Candidate = () => {
|
|||||||
<div className="col-12 candidate__header">
|
<div className="col-12 candidate__header">
|
||||||
<div className="candidate__header__left">
|
<div className="candidate__header__left">
|
||||||
<h3>
|
<h3>
|
||||||
|
{currentCandidateObj.fio} {" "}
|
||||||
{currentCandidateObj.specification} {" "}
|
{currentCandidateObj.specification} {" "}
|
||||||
{SKILLS[currentCandidateObj.position_id]} {" "}
|
{SKILLS[currentCandidateObj.position_id]} {" "}
|
||||||
{LEVELS[currentCandidateObj.level]}
|
{LEVELS[currentCandidateObj.level]}
|
||||||
@ -238,5 +237,3 @@ const Candidate = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Candidate;
|
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
@use "sass:math";
|
@use "sass:math";
|
||||||
|
|
||||||
.candidate {
|
.candidate {
|
||||||
padding-top: 23px;
|
display: flex;
|
||||||
z-index: 0;
|
flex-direction: column;
|
||||||
|
|
||||||
&__wrapper {
|
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
min-height: 100vh;
|
|
||||||
|
.container {
|
||||||
|
margin-top: 23px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-breadcrumbs {
|
.profile-breadcrumbs {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
@ -32,13 +33,11 @@
|
|||||||
|
|
||||||
.col-xl-8 {
|
.col-xl-8 {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__main {
|
&__main {
|
||||||
margin-top: 60px;
|
margin-top: 60px;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: -1;
|
|
||||||
|
|
||||||
&-description {
|
&-description {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
|
@ -10,7 +10,7 @@ export const CardControl = ({ title, path, description, img }) => {
|
|||||||
<Link to={`/${path}`} className="control-card">
|
<Link to={`/${path}`} className="control-card">
|
||||||
<div className="control-card__about">
|
<div className="control-card__about">
|
||||||
<img src={img} alt="itemImg" />
|
<img src={img} alt="itemImg" />
|
||||||
<h3>{title}</h3>
|
<h3 dangerouslySetInnerHTML={{ __html: title }}></h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="control-card__info">
|
<div className="control-card__info">
|
||||||
<p dangerouslySetInnerHTML={{ __html: description }}></p>
|
<p dangerouslySetInnerHTML={{ __html: description }}></p>
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
max-width: 125px;
|
max-width: 165px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,9 @@ export const AuthHeader = () => {
|
|||||||
<span>Главная</span>
|
<span>Главная</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
{/*<li>*/}
|
||||||
<NavLink to={"/auth"}>Кабинет разработчика</NavLink>
|
{/* <NavLink to={"/profile"}>Кабинет разработчика</NavLink>*/}
|
||||||
</li>
|
{/*</li>*/}
|
||||||
<li>
|
<li>
|
||||||
<NavLink to={"/tracker-intro"}>Трекер</NavLink>
|
<NavLink to={"/tracker-intro"}>Трекер</NavLink>
|
||||||
</li>
|
</li>
|
||||||
@ -51,5 +51,3 @@ export const AuthHeader = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AuthHeader;
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
|
||||||
.auth-nav {
|
.auth-nav {
|
||||||
|
height: 35px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -48,11 +49,13 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:focus, a.active {
|
a:focus,
|
||||||
|
a.active {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.candidate {
|
.candidate {
|
||||||
|
background: transparent;
|
||||||
color: #1458dd;
|
color: #1458dd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
border-radius: 44px;
|
border-radius: 44px;
|
||||||
color: white;
|
color: white;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
border: none;
|
border: none;
|
||||||
transition: 0.5s;
|
transition: 0.5s;
|
||||||
|
|
||||||
|
@ -5,19 +5,25 @@ import "./modalLayout.scss";
|
|||||||
export const ModalLayout = ({
|
export const ModalLayout = ({
|
||||||
active,
|
active,
|
||||||
setActive,
|
setActive,
|
||||||
|
onClose,
|
||||||
children,
|
children,
|
||||||
styles,
|
styles,
|
||||||
type,
|
type,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
|
const handleClose = (event) => {
|
||||||
|
if (event.target.className === "modal-layout active") {
|
||||||
|
setActive(false);
|
||||||
|
if (onClose) {
|
||||||
|
onClose(); // Вызов колбэк-функции при закрытии модального окна
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={active ? `modal-layout active` : "modal-layout"}
|
className={active ? `modal-layout active` : "modal-layout"}
|
||||||
onClick={(event) => {
|
onClick={handleClose}
|
||||||
if (event.target.className === "modal-layout active") {
|
|
||||||
setActive(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
row-gap: 5px;
|
row-gap: 5px;
|
||||||
&__input {
|
&__input {
|
||||||
margin: 0;
|
margin: 10px 0 10px 0;
|
||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
|
|
||||||
@ -79,6 +79,9 @@
|
|||||||
max-width: 190px;
|
max-width: 190px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.email-error-message {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 805px) {
|
@media (max-width: 805px) {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__empty {
|
&__empty {
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -4,10 +4,15 @@ import { backendImg } from "@utils/helper";
|
|||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
import close from "assets/icons/closeProjectPersons.svg";
|
import close from "assets/icons/closeProjectPersons.svg";
|
||||||
|
|
||||||
const FileTracker = ({ file, setDeletedTask, taskId }) => {
|
const FileTracker = ({ file, setDeletedTask, taskId }) => {
|
||||||
const [openImg, setOpenImg] = useState(false);
|
const [openImg, setOpenImg] = useState(false);
|
||||||
|
|
||||||
|
const { showNotification } = useNotification();
|
||||||
|
|
||||||
function deleteFile(file) {
|
function deleteFile(file) {
|
||||||
apiRequest("/file/detach", {
|
apiRequest("/file/detach", {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
@ -17,8 +22,21 @@ const FileTracker = ({ file, setDeletedTask, taskId }) => {
|
|||||||
entity_id: taskId,
|
entity_id: taskId,
|
||||||
status: 0
|
status: 0
|
||||||
}
|
}
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
setDeletedTask(file);
|
setDeletedTask(file);
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Файл успешно удален",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка при удалении файла",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import withReactContent from "sweetalert2-react-content";
|
|||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
|
|
||||||
import "./form.scss";
|
import "./form.scss";
|
||||||
@ -18,6 +20,8 @@ const Form = () => {
|
|||||||
|
|
||||||
const urlParams = useParams();
|
const urlParams = useParams();
|
||||||
|
|
||||||
|
const { showNotification } = useNotification();
|
||||||
|
|
||||||
const [status, setStatus] = useState(null);
|
const [status, setStatus] = useState(null);
|
||||||
const [data, setData] = useState({
|
const [data, setData] = useState({
|
||||||
email: "",
|
email: "",
|
||||||
@ -75,9 +79,22 @@ const Form = () => {
|
|||||||
profile_id: urlParams.id,
|
profile_id: urlParams.id,
|
||||||
...data
|
...data
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
})
|
||||||
|
.then((res) => {
|
||||||
setStatus(res);
|
setStatus(res);
|
||||||
setIsFetching(false);
|
setIsFetching(false);
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Отправка успешно завершена",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка отправки",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
|
|||||||
|
|
||||||
import { scrollToForm } from "@utils/helper";
|
import { scrollToForm } from "@utils/helper";
|
||||||
|
|
||||||
import AuthHeader from "@components/Common/AuthHeader/AuthHeader";
|
import { AuthHeader } from "@components/Common/AuthHeader/AuthHeader";
|
||||||
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
||||||
import { Footer } from "@components/Common/Footer/Footer";
|
import { Footer } from "@components/Common/Footer/Footer";
|
||||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.free-dev {
|
.free-dev {
|
||||||
font-family: "LabGrotesque", sans-serif;
|
display: flex;
|
||||||
overflow: hidden;
|
flex-direction: column;
|
||||||
position: relative;
|
min-height: 100vh;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
@ -29,7 +29,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&_page {
|
&_page {
|
||||||
margin: 24px 0 30px 0;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
color: #000000;
|
||||||
|
padding: 50px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { Link, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { useFormValidation } from "@hooks/useFormValidation";
|
import { useFormValidation } from "@hooks/useFormValidation";
|
||||||
import { useNotification } from "@hooks/useNotification";
|
import { useNotification } from "@hooks/useNotification";
|
||||||
@ -17,6 +18,7 @@ import "./modalRegistration.scss";
|
|||||||
export const ModalRegistration = ({ active, setActive }) => {
|
export const ModalRegistration = ({ active, setActive }) => {
|
||||||
const [loader, setLoader] = useState(false);
|
const [loader, setLoader] = useState(false);
|
||||||
const [isPartner, setIsPartner] = useState(false);
|
const [isPartner, setIsPartner] = useState(false);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const fields = {
|
const fields = {
|
||||||
username: "",
|
username: "",
|
||||||
@ -32,10 +34,10 @@ export const ModalRegistration = ({ active, setActive }) => {
|
|||||||
const apiEndpoint = "/register/sign-up";
|
const apiEndpoint = "/register/sign-up";
|
||||||
|
|
||||||
const { showNotification } = useNotification();
|
const { showNotification } = useNotification();
|
||||||
const showNotificationError = () => {
|
const showNotificationError = (error) => {
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
text: "Аккаунт с таким логином или email уже существует",
|
text: error,
|
||||||
type: "error"
|
type: "error"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -58,7 +60,9 @@ export const ModalRegistration = ({ active, setActive }) => {
|
|||||||
fields,
|
fields,
|
||||||
showNotificationError,
|
showNotificationError,
|
||||||
showNotificationTrue,
|
showNotificationTrue,
|
||||||
isPartner
|
isPartner,
|
||||||
|
setLoader,
|
||||||
|
closeModal
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -137,17 +141,13 @@ export const ModalRegistration = ({ active, setActive }) => {
|
|||||||
|
|
||||||
<div className="button-box">
|
<div className="button-box">
|
||||||
{loader ? (
|
{loader ? (
|
||||||
<Loader style={"green"} />
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<BaseButton
|
<BaseButton
|
||||||
onClick={async (e) => {
|
onClick={async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoader(true);
|
await handleSubmit(e);
|
||||||
const result = await handleSubmit(e);
|
navigate("/welcome-page");
|
||||||
if (result === true) {
|
|
||||||
closeModal();
|
|
||||||
}
|
|
||||||
setLoader(false);
|
|
||||||
}}
|
}}
|
||||||
styles="button-box__submit"
|
styles="button-box__submit"
|
||||||
>
|
>
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 65%;
|
width: 65%;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
@media (max-width: 1106px) {
|
@media (max-width: 1106px) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -115,6 +116,8 @@
|
|||||||
.input-container {
|
.input-container {
|
||||||
margin: 0 0 20px 0;
|
margin: 0 0 20px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
@ -246,6 +249,5 @@
|
|||||||
|
|
||||||
.loader {
|
.loader {
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
left: 80px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { useNotification } from "@hooks/useNotification";
|
|||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
||||||
|
|
||||||
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
import arrow from "assets/icons/arrows/arrowRight.png";
|
||||||
import close from "assets/icons/close.png";
|
import close from "assets/icons/close.png";
|
||||||
|
|
||||||
import "./modalResetPassword.scss";
|
import "./modalResetPassword.scss";
|
||||||
|
@ -6,10 +6,12 @@ import {
|
|||||||
modalToggle
|
modalToggle
|
||||||
} from "@redux/projectsTrackerSlice";
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import { caseOfNum, urlForLocal } from "@utils/helper";
|
import { caseOfNum, removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
||||||
|
|
||||||
import close from "assets/icons/close.png";
|
import close from "assets/icons/close.png";
|
||||||
@ -24,6 +26,7 @@ const ListEmployees = ({
|
|||||||
setModalAdd
|
setModalAdd
|
||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
const { showNotification } = useNotification();
|
||||||
|
|
||||||
function deletePerson(userId) {
|
function deletePerson(userId) {
|
||||||
apiRequest("/project/del-user", {
|
apiRequest("/project/del-user", {
|
||||||
@ -32,8 +35,21 @@ const ListEmployees = ({
|
|||||||
project_id: projectBoard.id,
|
project_id: projectBoard.id,
|
||||||
user_id: userId
|
user_id: userId
|
||||||
}
|
}
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
dispatch(deletePersonOnProject(userId));
|
dispatch(deletePersonOnProject(userId));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Участник успешно удален",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка удаления участника",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +83,7 @@ const ListEmployees = ({
|
|||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
className="delete"
|
className="delete"
|
||||||
src={close}
|
src={close}
|
||||||
|
@ -11,10 +11,10 @@ import { getProfileInfo } from "@redux/outstaffingSlice";
|
|||||||
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
|
import { setProjectBoardFetch } from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
backendImg,
|
|
||||||
caseOfNum,
|
caseOfNum,
|
||||||
getCorrectRequestDate,
|
getCorrectRequestDate,
|
||||||
getToken,
|
getToken,
|
||||||
|
removeLast,
|
||||||
urlForLocal
|
urlForLocal
|
||||||
} from "@utils/helper";
|
} from "@utils/helper";
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ import send from "assets/icons/send.svg";
|
|||||||
import watch from "assets/icons/watch.svg";
|
import watch from "assets/icons/watch.svg";
|
||||||
import avatarMok from "assets/images/avatarMok.png";
|
import avatarMok from "assets/images/avatarMok.png";
|
||||||
|
|
||||||
import { getCorrectDate } from "../../../Calendar/calendarHelper";
|
import { getCorrectDate } from "../../../../utils/calendarHelper";
|
||||||
import "./modalTicket.scss";
|
import "./modalTicket.scss";
|
||||||
|
|
||||||
registerLocale("ru", ru);
|
registerLocale("ru", ru);
|
||||||
@ -99,6 +99,18 @@ export const ModalTiсket = ({
|
|||||||
const { showNotification } = useNotification();
|
const { showNotification } = useNotification();
|
||||||
const [commentSendDisable, setCommentSendDisable] = useState(false);
|
const [commentSendDisable, setCommentSendDisable] = useState(false);
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
setActive(false);
|
||||||
|
// Восстанавливаем скролл при закрытии модального окна
|
||||||
|
document.body.style.overflow = "auto";
|
||||||
|
};
|
||||||
|
|
||||||
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
|
||||||
|
const toggleModalSize = () => {
|
||||||
|
setIsExpanded((prevState) => !prevState);
|
||||||
|
};
|
||||||
|
|
||||||
function deleteTask() {
|
function deleteTask() {
|
||||||
apiRequest("/task/update-task", {
|
apiRequest("/task/update-task", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
@ -106,13 +118,21 @@ export const ModalTiсket = ({
|
|||||||
task_id: task.id,
|
task_id: task.id,
|
||||||
status: 0
|
status: 0
|
||||||
}
|
}
|
||||||
}).then(() => {
|
})
|
||||||
setActive(false);
|
.then(() => {
|
||||||
|
closeModal();
|
||||||
dispatch(setProjectBoardFetch(projectId));
|
dispatch(setProjectBoardFetch(projectId));
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
text: "Задача успешно была перемещена в архив",
|
text: "Задача успешно удалена",
|
||||||
type: "archive"
|
type: "success"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка удаления",
|
||||||
|
type: "error"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -157,7 +177,8 @@ export const ModalTiсket = ({
|
|||||||
title: inputsValue.title,
|
title: inputsValue.title,
|
||||||
description: inputsValue.description
|
description: inputsValue.description
|
||||||
}
|
}
|
||||||
}).then((res) => {
|
})
|
||||||
|
.then((res) => {
|
||||||
setEditOpen(!editOpen);
|
setEditOpen(!editOpen);
|
||||||
dispatch(setProjectBoardFetch(projectId));
|
dispatch(setProjectBoardFetch(projectId));
|
||||||
showNotification({
|
showNotification({
|
||||||
@ -165,6 +186,13 @@ export const ModalTiсket = ({
|
|||||||
text: "Изменения сохранены",
|
text: "Изменения сохранены",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка при сохранении изменений",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,20 +622,20 @@ export const ModalTiсket = ({
|
|||||||
<div
|
<div
|
||||||
className={active ? "modal-ticket active" : "modal-ticket"}
|
className={active ? "modal-ticket active" : "modal-ticket"}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (e.target.className.includes("modal-ticket")) setActive(false);
|
if (e.target.className.includes("modal-ticket")) closeModal();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="modal-ticket__content">
|
<div className={`modal-ticket__content ${isExpanded ? "expanded" : ""}`}>
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<h3 className="title-project">
|
<h3 className="title-project">
|
||||||
<img src={category} className="title-project__category"></img>
|
<img src={category} className="title-project__category"></img>
|
||||||
{projectName}
|
{projectName}
|
||||||
<Link
|
<img
|
||||||
to={`/tracker/task/${task.id}`}
|
src={fullScreen}
|
||||||
|
alt="Full screen"
|
||||||
|
onClick={toggleModalSize}
|
||||||
className="title-project__full"
|
className="title-project__full"
|
||||||
>
|
/>
|
||||||
<img src={fullScreen}></img>
|
|
||||||
</Link>
|
|
||||||
</h3>
|
</h3>
|
||||||
<div className="content__task">
|
<div className="content__task">
|
||||||
{editOpen ? (
|
{editOpen ? (
|
||||||
@ -636,11 +664,8 @@ export const ModalTiсket = ({
|
|||||||
"EasyImage",
|
"EasyImage",
|
||||||
"Image",
|
"Image",
|
||||||
"ImageCaption",
|
"ImageCaption",
|
||||||
"ImageStyle",
|
|
||||||
"ImageToolbar",
|
|
||||||
"ImageUpload",
|
"ImageUpload",
|
||||||
"MediaEmbed",
|
"MediaEmbed"
|
||||||
"BlockQuote"
|
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
@ -757,14 +782,14 @@ export const ModalTiсket = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="workers">
|
<div className="workers">
|
||||||
<div className="workers_box task__info">
|
<div className="workers_box task__info">
|
||||||
<span className="exit" onClick={() => setActive(false)}></span>
|
<span className="exit" onClick={() => closeModal()}></span>
|
||||||
<h5>Создатель: </h5>
|
<h5>Создатель: </h5>
|
||||||
<p className="workers__creator">{task.user?.fio}</p>
|
<p className="workers__creator">{removeLast(task.user?.fio)}</p>
|
||||||
{executor ? (
|
{executor ? (
|
||||||
<>
|
<>
|
||||||
<h5>Исполнитель: </h5>
|
<h5>Исполнитель: </h5>
|
||||||
<div className="executor">
|
<div className="executor">
|
||||||
<p>{executor.fio}</p>
|
<p>{removeLast(executor.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
executor?.avatar
|
executor?.avatar
|
||||||
@ -803,7 +828,7 @@ export const ModalTiсket = ({
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => taskExecutor(person)}
|
onClick={() => taskExecutor(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -826,7 +851,7 @@ export const ModalTiсket = ({
|
|||||||
{members.map((member) => {
|
{members.map((member) => {
|
||||||
return (
|
return (
|
||||||
<div className="worker" key={member.user_id}>
|
<div className="worker" key={member.user_id}>
|
||||||
<p>{member.fio}</p>
|
<p>{removeLast(member.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
member?.avatar
|
member?.avatar
|
||||||
@ -869,7 +894,7 @@ export const ModalTiсket = ({
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => addMember(person)}
|
onClick={() => addMember(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -895,7 +920,7 @@ export const ModalTiсket = ({
|
|||||||
className="dead-line__container"
|
className="dead-line__container"
|
||||||
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
||||||
>
|
>
|
||||||
<img src={calendarIcon} alt="calendar" />
|
<p>⌛</p>
|
||||||
<span>
|
<span>
|
||||||
{deadLine ? getCorrectDate(deadLine) : "Срок исполнения"}
|
{deadLine ? getCorrectDate(deadLine) : "Срок исполнения"}
|
||||||
</span>
|
</span>
|
||||||
|
@ -15,13 +15,20 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-ticket__content.expanded {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
max-height: none;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-ticket__content {
|
.modal-ticket__content {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
max-height: 700px;
|
max-height: 700px;
|
||||||
// overflow-y: auto;
|
max-width: 915px;
|
||||||
|
|
||||||
@media (max-width: 990px) {
|
@media (max-width: 990px) {
|
||||||
width: 96%;
|
width: 96%;
|
||||||
@ -52,7 +59,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 630px;
|
width: 68%;
|
||||||
margin: 26px 0 0 21px;
|
margin: 26px 0 0 21px;
|
||||||
|
|
||||||
.title-project {
|
.title-project {
|
||||||
@ -77,7 +84,6 @@
|
|||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
color: #1458dd;
|
color: #1458dd;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@ -161,7 +167,6 @@
|
|||||||
|
|
||||||
.comments__list {
|
.comments__list {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow-y: auto;
|
|
||||||
height: 190px;
|
height: 190px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -365,7 +370,6 @@
|
|||||||
column-gap: 25px;
|
column-gap: 25px;
|
||||||
row-gap: 20px;
|
row-gap: 20px;
|
||||||
margin-top: 33px;
|
margin-top: 33px;
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.task-file {
|
.task-file {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -608,6 +612,7 @@
|
|||||||
.workers {
|
.workers {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-left: 1px solid #f1f1f1;
|
border-left: 1px solid #f1f1f1;
|
||||||
|
width: 32%;
|
||||||
|
|
||||||
.exit {
|
.exit {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -780,7 +785,6 @@
|
|||||||
|
|
||||||
.react-datepicker__current-month {
|
.react-datepicker__current-month {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +827,6 @@
|
|||||||
.react-datepicker__day {
|
.react-datepicker__day {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
}
|
}
|
||||||
@ -832,7 +835,6 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-datepicker__triangle {
|
.react-datepicker__triangle {
|
||||||
@ -980,7 +982,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
row-gap: 10px;
|
row-gap: 10px;
|
||||||
padding: 10px 40px 0px 20px;
|
padding: 10px 20px 0px 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
@ -1111,7 +1113,7 @@
|
|||||||
|
|
||||||
&-priority {
|
&-priority {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 10px 40px 0 20px;
|
padding: 10px 20px 0 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
.priority {
|
.priority {
|
||||||
@ -1171,7 +1173,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-bottom {
|
&-bottom {
|
||||||
padding: 0px 90px 10px 35px;
|
padding: 0px 30px 10px 20px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
@ -1194,9 +1196,10 @@
|
|||||||
.edit {
|
.edit {
|
||||||
background: #52b709;
|
background: #52b709;
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
|
width: fit-content;
|
||||||
p {
|
p {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,13 @@ import { Link, useNavigate, useParams } from "react-router-dom";
|
|||||||
import { getProfileInfo } from "@redux/outstaffingSlice";
|
import { getProfileInfo } from "@redux/outstaffingSlice";
|
||||||
import { getBoarderLoader, setToggleTab } from "@redux/projectsTrackerSlice";
|
import { getBoarderLoader, setToggleTab } from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
import {
|
import {
|
||||||
backendImg,
|
backendImg,
|
||||||
caseOfNum,
|
caseOfNum,
|
||||||
getCorrectRequestDate,
|
getCorrectRequestDate,
|
||||||
getToken,
|
getToken,
|
||||||
|
removeLast,
|
||||||
urlForLocal
|
urlForLocal
|
||||||
} from "@utils/helper";
|
} from "@utils/helper";
|
||||||
|
|
||||||
@ -21,7 +23,6 @@ import { apiRequest } from "@api/request";
|
|||||||
|
|
||||||
import { useNotification } from "@hooks/useNotification";
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
import { getCorrectDate } from "@components/Calendar/calendarHelper";
|
|
||||||
import { Footer } from "@components/Common/Footer/Footer";
|
import { Footer } from "@components/Common/Footer/Footer";
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
import FileTracker from "@components/FileTracker/FileTracker";
|
import FileTracker from "@components/FileTracker/FileTracker";
|
||||||
@ -31,12 +32,12 @@ import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadc
|
|||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
import TrackerTaskComment from "@components/TrackerTaskComment/TrackerTaskComment";
|
import TrackerTaskComment from "@components/TrackerTaskComment/TrackerTaskComment";
|
||||||
|
|
||||||
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
import arrow from "assets/icons/arrows/arrowRight.png";
|
||||||
import arrowStart from "assets/icons/arrows/arrowStart.png";
|
import arrowStart from "assets/icons/arrows/arrowStart.png";
|
||||||
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
||||||
import calendarIcon from "assets/icons/calendar.svg";
|
import calendarIcon from "assets/icons/calendar.svg";
|
||||||
import close from "assets/icons/close.png";
|
|
||||||
import fileDelete from "assets/icons/closeProjectPersons.svg";
|
import fileDelete from "assets/icons/closeProjectPersons.svg";
|
||||||
|
import close from "assets/icons/crossWhite.svg";
|
||||||
import del from "assets/icons/delete.svg";
|
import del from "assets/icons/delete.svg";
|
||||||
import edit from "assets/icons/edit.svg";
|
import edit from "assets/icons/edit.svg";
|
||||||
import file from "assets/icons/fileModal.svg";
|
import file from "assets/icons/fileModal.svg";
|
||||||
@ -630,14 +631,6 @@ export const TicketFullScreen = () => {
|
|||||||
<img src={tasks} alt="img" />
|
<img src={tasks} alt="img" />
|
||||||
<p>Все мои задачи</p>
|
<p>Все мои задачи</p>
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
|
||||||
to="/profile/tracker"
|
|
||||||
className="tab"
|
|
||||||
onClick={() => toggleTabs(3)}
|
|
||||||
>
|
|
||||||
<img src={archive} alt="img" />
|
|
||||||
<p>Архив</p>
|
|
||||||
</Link>
|
|
||||||
</div>
|
</div>
|
||||||
{loader ? (
|
{loader ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
@ -690,11 +683,8 @@ export const TicketFullScreen = () => {
|
|||||||
"EasyImage",
|
"EasyImage",
|
||||||
"Image",
|
"Image",
|
||||||
"ImageCaption",
|
"ImageCaption",
|
||||||
"ImageStyle",
|
|
||||||
"ImageToolbar",
|
|
||||||
"ImageUpload",
|
"ImageUpload",
|
||||||
"MediaEmbed",
|
"MediaEmbed"
|
||||||
"BlockQuote"
|
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
@ -812,14 +802,14 @@ export const TicketFullScreen = () => {
|
|||||||
<div className="workers fullscreen-workers">
|
<div className="workers fullscreen-workers">
|
||||||
<div className="workers_box task__info">
|
<div className="workers_box task__info">
|
||||||
<div className="workers__creator">
|
<div className="workers__creator">
|
||||||
Создатель: <p>{taskInfo.user?.fio}</p>
|
Создатель: <p>{removeLast(taskInfo.user?.fio)}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{taskInfo.executor ? (
|
{taskInfo.executor ? (
|
||||||
<>
|
<>
|
||||||
<h5>Исполнитель: </h5>
|
<h5>Исполнитель: </h5>
|
||||||
<div className="executor">
|
<div className="executor">
|
||||||
<p>{taskInfo.executor.fio}</p>
|
<p>{removeLast(taskInfo.executor.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
taskInfo.executor?.avatar
|
taskInfo.executor?.avatar
|
||||||
@ -858,7 +848,7 @@ export const TicketFullScreen = () => {
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => taskExecutor(person)}
|
onClick={() => taskExecutor(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -881,7 +871,7 @@ export const TicketFullScreen = () => {
|
|||||||
{taskInfo.taskUsers.map((member) => {
|
{taskInfo.taskUsers.map((member) => {
|
||||||
return (
|
return (
|
||||||
<div className="worker" key={member.user_id}>
|
<div className="worker" key={member.user_id}>
|
||||||
<p>{member.fio}</p>
|
<p>{removeLast(member.fio)}</p>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
member?.avatar
|
member?.avatar
|
||||||
@ -924,7 +914,7 @@ export const TicketFullScreen = () => {
|
|||||||
key={person.user_id}
|
key={person.user_id}
|
||||||
onClick={() => addMember(person)}
|
onClick={() => addMember(person)}
|
||||||
>
|
>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
person.user?.avatar
|
person.user?.avatar
|
||||||
@ -950,7 +940,7 @@ export const TicketFullScreen = () => {
|
|||||||
className="dead-line__container"
|
className="dead-line__container"
|
||||||
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
onClick={() => setDatePickerOpen(!datePickerOpen)}
|
||||||
>
|
>
|
||||||
<img src={calendarIcon} alt="calendar" />
|
<p>⌛</p>
|
||||||
<span>
|
<span>
|
||||||
{deadLine
|
{deadLine
|
||||||
? getCorrectDate(deadLine)
|
? getCorrectDate(deadLine)
|
||||||
@ -971,7 +961,7 @@ export const TicketFullScreen = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="time">
|
<div className="time">
|
||||||
<img src={watch}></img>
|
<p>⏱</p>
|
||||||
<p>
|
<p>
|
||||||
{correctTimerTime(currentTimerCount.hours)}:
|
{correctTimerTime(currentTimerCount.hours)}:
|
||||||
{correctTimerTime(currentTimerCount.minute)}:
|
{correctTimerTime(currentTimerCount.minute)}:
|
||||||
|
@ -49,8 +49,6 @@
|
|||||||
|
|
||||||
.fullscreen-workers {
|
.fullscreen-workers {
|
||||||
@media (max-width: 880px) {
|
@media (max-width: 880px) {
|
||||||
background: #dff1ff;
|
|
||||||
|
|
||||||
.workers_box {
|
.workers_box {
|
||||||
@media (max-width: 880px) {
|
@media (max-width: 880px) {
|
||||||
flex-direction: inherit !important;
|
flex-direction: inherit !important;
|
||||||
|
@ -22,13 +22,13 @@ import {
|
|||||||
setProjectBoardFetch
|
setProjectBoardFetch
|
||||||
} from "@redux/projectsTrackerSlice";
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
import { getCorrectRequestDate, urlForLocal } from "@utils/helper";
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
|
import { getCorrectRequestDate, removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { useNotification } from "@hooks/useNotification";
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
import { getCorrectDate } from "@components/Calendar/calendarHelper";
|
|
||||||
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
import ModalLayout from "@components/Common/ModalLayout/ModalLayout";
|
||||||
@ -72,6 +72,7 @@ export const TrackerModal = ({
|
|||||||
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
|
const [selectWorkersOpen, setSelectWorkersOpen] = useState(false);
|
||||||
const [selectedWorker, setSelectedWorker] = useState(null);
|
const [selectedWorker, setSelectedWorker] = useState(null);
|
||||||
const [emailWorker, setEmailWorker] = useState("");
|
const [emailWorker, setEmailWorker] = useState("");
|
||||||
|
const [emailError, setEmailError] = useState("");
|
||||||
const [selectColumnPriority, setSelectColumnPriority] = useState(
|
const [selectColumnPriority, setSelectColumnPriority] = useState(
|
||||||
"Выберите приоритет колонки"
|
"Выберите приоритет колонки"
|
||||||
);
|
);
|
||||||
@ -114,6 +115,19 @@ export const TrackerModal = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingColumn = projectBoard.columns.find(
|
||||||
|
(column) => column.title === valueColumn
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingColumn) {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Колонка с таким названием уже существует",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
apiRequest("/project-column/create-column", {
|
apiRequest("/project-column/create-column", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -123,8 +137,21 @@ export const TrackerModal = ({
|
|||||||
: 1,
|
: 1,
|
||||||
title: valueColumn
|
title: valueColumn
|
||||||
}
|
}
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
dispatch(setProjectBoardFetch(projectBoard.id));
|
dispatch(setProjectBoardFetch(projectBoard.id));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Колонка успешно создана",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ошибка при создании колонки",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
setValueColumn("");
|
setValueColumn("");
|
||||||
setActive(false);
|
setActive(false);
|
||||||
@ -202,7 +229,7 @@ export const TrackerModal = ({
|
|||||||
setDeadLineDate("");
|
setDeadLineDate("");
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
text: "Задача создана",
|
text: "Задача успешно создана",
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -219,6 +246,11 @@ export const TrackerModal = ({
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
setActive(false);
|
setActive(false);
|
||||||
dispatch(editProjectName({ id: projectId, name: projectName }));
|
dispatch(editProjectName({ id: projectId, name: projectName }));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Название проекта успешно изменено",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,8 +299,25 @@ export const TrackerModal = ({
|
|||||||
title: columnName
|
title: columnName
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
const existingColumn = projectBoard.columns.find(
|
||||||
|
(column) => column.title === columnName
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingColumn) {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Колонка с таким названием уже существует",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
setActive(false);
|
setActive(false);
|
||||||
dispatch(editColumnName({ id: columnId, title: columnName }));
|
dispatch(editColumnName({ id: columnId, title: columnName }));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Колонка успешно изменена",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,6 +336,11 @@ export const TrackerModal = ({
|
|||||||
dispatch(setProject(result));
|
dispatch(setProject(result));
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setNameProject("");
|
setNameProject("");
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Проект успешно создан",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
showNotification({
|
showNotification({
|
||||||
show: true,
|
show: true,
|
||||||
@ -310,21 +364,57 @@ export const TrackerModal = ({
|
|||||||
setActive(false);
|
setActive(false);
|
||||||
setSelectedWorker("");
|
setSelectedWorker("");
|
||||||
setSelectWorkersOpen(false);
|
setSelectWorkersOpen(false);
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Приглашение отправлено",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function inviteUserByEmail() {
|
const validateEmail = (email) => {
|
||||||
|
// Простая валидация адреса электронной почты
|
||||||
|
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
return emailPattern.test(email);
|
||||||
|
};
|
||||||
|
|
||||||
|
const inviteUserByEmail = () => {
|
||||||
|
if (validateEmail(emailWorker)) {
|
||||||
|
setEmailError("");
|
||||||
apiRequest("/project/add-user-by-email", {
|
apiRequest("/project/add-user-by-email", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
email: emailWorker,
|
email: emailWorker,
|
||||||
project_id: projectBoard.id
|
project_id: projectBoard.id
|
||||||
}
|
}
|
||||||
}).then((el) => {
|
}).then((response) => {
|
||||||
|
if (response.status === 400) {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Участник уже добавлен в проект",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
} else if (response.status === 404) {
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Данной почты не существует",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
setActive(false);
|
setActive(false);
|
||||||
setEmailWorker("");
|
setEmailWorker("");
|
||||||
|
dispatch(addPersonToProject(response));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Приглашение отправлено",
|
||||||
|
type: "success"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setEmailError("Некорректный e-mail адрес");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
modalType === "add-worker"
|
modalType === "add-worker"
|
||||||
@ -406,8 +496,18 @@ export const TrackerModal = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleModalClose = () => {
|
||||||
|
setEmailError("");
|
||||||
|
setEmailWorker("");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalLayout active={active} setActive={setActive} type={modalType}>
|
<ModalLayout
|
||||||
|
active={active}
|
||||||
|
setActive={setActive}
|
||||||
|
onClose={handleModalClose}
|
||||||
|
type={modalType}
|
||||||
|
>
|
||||||
{modalType === "add-worker" && (
|
{modalType === "add-worker" && (
|
||||||
<>
|
<>
|
||||||
<div className="select__person">
|
<div className="select__person">
|
||||||
@ -428,7 +528,7 @@ export const TrackerModal = ({
|
|||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
{selectedWorker
|
{selectedWorker
|
||||||
? selectedWorker.employee.fio
|
? removeLast(selectedWorker.employee.fio)
|
||||||
: "Выберите пользователя"}
|
: "Выберите пользователя"}
|
||||||
</p>
|
</p>
|
||||||
<img className="arrow" src={arrowDown} alt="arrow" />
|
<img className="arrow" src={arrowDown} alt="arrow" />
|
||||||
@ -447,7 +547,7 @@ export const TrackerModal = ({
|
|||||||
setSelectedWorker(worker);
|
setSelectedWorker(worker);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{worker.employee.fio}</span>
|
<span>{removeLast(worker.employee.fio)}</span>
|
||||||
<img
|
<img
|
||||||
src={urlForLocal(worker.employee.avatar)}
|
src={urlForLocal(worker.employee.avatar)}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
@ -478,6 +578,7 @@ export const TrackerModal = ({
|
|||||||
value={emailWorker}
|
value={emailWorker}
|
||||||
onChange={(e) => setEmailWorker(e.target.value)}
|
onChange={(e) => setEmailWorker(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
<div className="email-error-message">{emailError}</div>
|
||||||
</div>
|
</div>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
styles={"button-add add-person-btn"}
|
styles={"button-add add-person-btn"}
|
||||||
@ -501,7 +602,6 @@ export const TrackerModal = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="create-task-body">
|
<div className="create-task-body">
|
||||||
<div className="create-task-body__left">
|
<div className="create-task-body__left">
|
||||||
<h4>Введите название и описание задачи</h4>
|
|
||||||
<div className="input-container">
|
<div className="input-container">
|
||||||
<input
|
<input
|
||||||
maxLength="100"
|
maxLength="100"
|
||||||
@ -524,7 +624,15 @@ export const TrackerModal = ({
|
|||||||
"bulletedList",
|
"bulletedList",
|
||||||
"numberedList"
|
"numberedList"
|
||||||
],
|
],
|
||||||
removePlugins: ["BlockQuote"],
|
removePlugins: [
|
||||||
|
"CKFinderUploadAdapter",
|
||||||
|
"CKFinder",
|
||||||
|
"EasyImage",
|
||||||
|
"Image",
|
||||||
|
"ImageCaption",
|
||||||
|
"ImageUpload",
|
||||||
|
"MediaEmbed"
|
||||||
|
],
|
||||||
placeholder: "Описание задачи"
|
placeholder: "Описание задачи"
|
||||||
}}
|
}}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
@ -653,7 +761,7 @@ export const TrackerModal = ({
|
|||||||
src={urlForLocal(selectedExecutorTask.user.avatar)}
|
src={urlForLocal(selectedExecutorTask.user.avatar)}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>{selectedExecutorTask.user.fio}</span>
|
<span>{removeLast(selectedExecutorTask.user.fio)}</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<span>{selectedExecutorTask}</span>
|
<span>{selectedExecutorTask}</span>
|
||||||
@ -679,7 +787,7 @@ export const TrackerModal = ({
|
|||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<span>{person.user.fio}</span>
|
<span>{removeLast(person.user.fio)}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
@ -690,7 +798,7 @@ export const TrackerModal = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="create-task-body__right__dead-line">
|
<div className="create-task-body__right__dead-line">
|
||||||
<img src={calendarImg} alt="calendar" />
|
<p>⌛</p>
|
||||||
<p onClick={() => setDatePickerOpen(!datePickerOpen)}>
|
<p onClick={() => setDatePickerOpen(!datePickerOpen)}>
|
||||||
{deadLineDate
|
{deadLineDate
|
||||||
? getCorrectDate(deadLineDate)
|
? getCorrectDate(deadLineDate)
|
||||||
@ -714,7 +822,7 @@ export const TrackerModal = ({
|
|||||||
<Loader style={"green"} />
|
<Loader style={"green"} />
|
||||||
) : (
|
) : (
|
||||||
<BaseButton styles={"button-add"} onClick={createTicket}>
|
<BaseButton styles={"button-add"} onClick={createTicket}>
|
||||||
Создать
|
Создать задачу
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -844,7 +952,14 @@ export const TrackerModal = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<span className="exit" onClick={() => setActive(false)}></span>
|
<span
|
||||||
|
className="exit"
|
||||||
|
onClick={() => {
|
||||||
|
setActive(false);
|
||||||
|
setEmailError("");
|
||||||
|
setEmailWorker("");
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
</ModalLayout>
|
</ModalLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -227,6 +227,7 @@
|
|||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -262,7 +263,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 9.5px 12px;
|
padding: 9.5px 12px;
|
||||||
top: 48px;
|
top: 45px;
|
||||||
left: 0;
|
left: 0;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@ -337,7 +338,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.create-task-body {
|
.create-task-body {
|
||||||
padding: 15px 20px;
|
padding: 15px 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
column-gap: 20px;
|
column-gap: 20px;
|
||||||
|
|
||||||
@ -373,8 +374,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ck-editor__editable.ck-rounded-corners {
|
.ck-editor__editable.ck-rounded-corners {
|
||||||
min-height: 150px;
|
min-height: 180px;
|
||||||
max-height: 150px;
|
max-height: 180px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +384,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
|
row-gap: 10px;
|
||||||
|
|
||||||
&__owner {
|
&__owner {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -651,7 +653,6 @@
|
|||||||
|
|
||||||
.react-datepicker__current-month {
|
.react-datepicker__current-month {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
@ -695,7 +696,6 @@
|
|||||||
.react-datepicker__day {
|
.react-datepicker__day {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
padding: 7px;
|
padding: 7px;
|
||||||
}
|
}
|
||||||
@ -704,7 +704,6 @@
|
|||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-datepicker__triangle {
|
.react-datepicker__triangle {
|
||||||
@ -717,6 +716,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-add {
|
||||||
|
margin: 0 30px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.name-project {
|
.name-project {
|
||||||
|
@ -29,10 +29,10 @@ export const Navigation = () => {
|
|||||||
path: "/tracker",
|
path: "/tracker",
|
||||||
name: "Трекер"
|
name: "Трекер"
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: "/payouts",
|
// path: "/payouts",
|
||||||
name: "Выплаты"
|
// name: "Выплаты"
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: "/quiz",
|
path: "/quiz",
|
||||||
name: "Тесты"
|
name: "Тесты"
|
||||||
@ -43,14 +43,14 @@ export const Navigation = () => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
partner: [
|
partner: [
|
||||||
{
|
// {
|
||||||
path: "/catalog",
|
// path: "/catalog",
|
||||||
active: "candidate",
|
// active: "candidate",
|
||||||
name: "Каталог"
|
// name: "Каталог"
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: "/requests",
|
path: "/requests",
|
||||||
name: "Запросы"
|
name: "Мои вакансии"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/employees",
|
path: "/employees",
|
||||||
@ -61,10 +61,10 @@ export const Navigation = () => {
|
|||||||
path: "/tracker",
|
path: "/tracker",
|
||||||
name: "Трекер"
|
name: "Трекер"
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: "/treaties",
|
// path: "/treaties",
|
||||||
name: "Договоры"
|
// name: "Договоры"
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
path: "/settings",
|
path: "/settings",
|
||||||
name: "Настройки"
|
name: "Настройки"
|
||||||
@ -81,7 +81,7 @@ export const Navigation = () => {
|
|||||||
<NavLink
|
<NavLink
|
||||||
key={index}
|
key={index}
|
||||||
end
|
end
|
||||||
to={link.path === "/Quiz" ? link.path : `/profile${link.path}`}
|
to={`/profile${link.path}`}
|
||||||
className={
|
className={
|
||||||
currentPath.includes(link.path) ||
|
currentPath.includes(link.path) ||
|
||||||
currentPath.includes(link.active)
|
currentPath.includes(link.active)
|
||||||
@ -97,7 +97,7 @@ export const Navigation = () => {
|
|||||||
|
|
||||||
<div className="profile-header__personal-info">
|
<div className="profile-header__personal-info">
|
||||||
<h3 className="profile-header__personal-info-name">
|
<h3 className="profile-header__personal-info-name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username}
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
</h3>
|
</h3>
|
||||||
<NavLink end to={"/profile"}>
|
<NavLink end to={"/profile"}>
|
||||||
<img
|
<img
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
body {
|
|
||||||
font-family: "LabGrotesque", sans-serif !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
max-width: 1160px !important;
|
|
||||||
}
|
|
||||||
.catalog {
|
.catalog {
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -18,6 +11,10 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1160px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.outstaffing-block__selected .outstaffing-block__img {
|
.outstaffing-block__selected .outstaffing-block__img {
|
||||||
background-color: #52b70999;
|
background-color: #52b70999;
|
||||||
color: #f9f9f9;
|
color: #f9f9f9;
|
||||||
|
@ -12,11 +12,11 @@ import {
|
|||||||
setRequestDate
|
setRequestDate
|
||||||
} from "@redux/reportSlice";
|
} from "@redux/reportSlice";
|
||||||
|
|
||||||
|
import { getReports } from "@utils/calendarHelper";
|
||||||
import { urlForLocal } from "@utils/helper";
|
import { urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { getReports } from "@components/Calendar/calendarHelper";
|
|
||||||
import { Footer } from "@components/Common/Footer/Footer";
|
import { Footer } from "@components/Common/Footer/Footer";
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
import { Navigation } from "@components/Navigation/Navigation";
|
import { Navigation } from "@components/Navigation/Navigation";
|
||||||
@ -95,11 +95,21 @@ export const ProfileCalendar = () => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<p className="summary__name">
|
<p className="summary__name">
|
||||||
{profileInfo?.fio ? profileInfo?.fio : profileInfo?.username},{" "}
|
{profileInfo?.fio || profileInfo?.username}{" "}
|
||||||
{profileInfo.specification} разработчик
|
{profileInfo.specification}
|
||||||
</p>
|
</p>
|
||||||
|
<hr />
|
||||||
|
<div className="summary__direction">Front End</div>
|
||||||
|
<div className="summary__level">Middle+</div>
|
||||||
</div>
|
</div>
|
||||||
<Link to="/profile/calendar/report">
|
<div className="summary__skill">
|
||||||
|
<p>Ключевые навыки:</p>
|
||||||
|
<div>Java</div>
|
||||||
|
<div>Java</div>
|
||||||
|
<div>Solid</div>
|
||||||
|
<div>Java</div>
|
||||||
|
</div>
|
||||||
|
{/* <Link to="/profile/calendar/report">
|
||||||
<button
|
<button
|
||||||
className="calendar__btn"
|
className="calendar__btn"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -109,7 +119,7 @@ export const ProfileCalendar = () => {
|
|||||||
>
|
>
|
||||||
Заполнить отчет
|
Заполнить отчет
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link> */}
|
||||||
</div>
|
</div>
|
||||||
{loader ? (
|
{loader ? (
|
||||||
<div className="loader__wrapper">
|
<div className="loader__wrapper">
|
||||||
|
@ -11,24 +11,23 @@ import {
|
|||||||
setSendRequest
|
setSendRequest
|
||||||
} from "@redux/reportSlice";
|
} from "@redux/reportSlice";
|
||||||
|
|
||||||
|
import {
|
||||||
|
calendarHelper,
|
||||||
|
correctDay,
|
||||||
|
getCorrectDate,
|
||||||
|
getReports,
|
||||||
|
hourOfNum
|
||||||
|
} from "@utils/calendarHelper";
|
||||||
import { getCorrectYYMMDD } from "@utils/helper";
|
import { getCorrectYYMMDD } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import "@components/Calendar/calendarComponent.scss";
|
import "@components/Calendar/calendarComponent.scss";
|
||||||
import {
|
|
||||||
calendarHelper,
|
|
||||||
correctDay,
|
|
||||||
currentMonthAndDay,
|
|
||||||
getCorrectDate,
|
|
||||||
getReports,
|
|
||||||
hourOfNum
|
|
||||||
} from "@components/Calendar/calendarHelper";
|
|
||||||
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
import BaseButton from "@components/Common/BaseButton/BaseButton";
|
||||||
|
|
||||||
import arrow from "assets/icons/arrows/arrowCalendar.png";
|
import arrowLeft from "assets/icons/arrows/arrowCalendar_left.png";
|
||||||
|
import arrowRight from "assets/icons/arrows/arrowCalendar_right.png";
|
||||||
import calendarIcon from "assets/icons/calendar.svg";
|
import calendarIcon from "assets/icons/calendar.svg";
|
||||||
// import close from "assets/icons/closeProjectPersons.svg";
|
|
||||||
import rectangle from "assets/images/rectangle__calendar.png";
|
import rectangle from "assets/images/rectangle__calendar.png";
|
||||||
|
|
||||||
export const ProfileCalendarComponent = React.memo(
|
export const ProfileCalendarComponent = React.memo(
|
||||||
@ -45,6 +44,7 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
}) => {
|
}) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
// const [l, setL] = useState(1);
|
||||||
const [calendar, setCalendar] = useState([]);
|
const [calendar, setCalendar] = useState([]);
|
||||||
const [month, setMonth] = useState("");
|
const [month, setMonth] = useState("");
|
||||||
const [endDate, setEndDate] = useState(null);
|
const [endDate, setEndDate] = useState(null);
|
||||||
@ -173,11 +173,18 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const countHours = (day) => {
|
||||||
|
let hours =
|
||||||
|
reports
|
||||||
|
.find((item) => moment(item.created_at).isSame(day, "date"))
|
||||||
|
?.task.reduce((acc, task) => acc + task.hours_spent, 0) || 0;
|
||||||
|
return `${hours} ${hourOfNum(hours)}`;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="calendar-component">
|
<div className="calendar-component">
|
||||||
<div className="calendar-component__header">
|
<div className="calendar-component__header">
|
||||||
<div className="calendar-component__header-info">
|
<div className="calendar-component__header-info">
|
||||||
{!userId && <h3>Мои отчеты за </h3>}
|
|
||||||
<p className="calendar__hours">
|
<p className="calendar__hours">
|
||||||
{month}
|
{month}
|
||||||
<span>
|
<span>
|
||||||
@ -187,27 +194,26 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
</div>
|
</div>
|
||||||
<div className="calendar-component__header-switcher">
|
<div className="calendar-component__header-switcher">
|
||||||
<div
|
<div
|
||||||
className="calendar-component__header-box"
|
className="calendar-component__header-arrow"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValueHandler(prevMonth());
|
setValueHandler(prevMonth());
|
||||||
dispatch(setRequestDate(getReports(prevMonth())));
|
dispatch(setRequestDate(getReports(prevMonth())));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img src={arrow} alt="" />
|
<img src={arrowLeft} alt="" />
|
||||||
<span>{prevMonth().format("MMMM")}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="calendar-component__header-box">
|
<div className="calendar-component__header-box">
|
||||||
<span>{value.format("YYYY")}</span>
|
<img className={"calendar__icon"} src={calendarIcon} alt="" />
|
||||||
|
<span>{value.format("MMMM, YYYY")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="calendar-component__header-box"
|
className="calendar-component__header-arrow"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValueHandler(nextMonth());
|
setValueHandler(nextMonth());
|
||||||
dispatch(setRequestDate(getReports(nextMonth())));
|
dispatch(setRequestDate(getReports(nextMonth())));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{nextMonth().format("MMMM")}</span>
|
<img src={arrowRight} alt="" />
|
||||||
<img src={arrow} alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -218,13 +224,13 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
|
|
||||||
<div className="calendar-component__body">
|
<div className="calendar-component__body">
|
||||||
<div>
|
<div>
|
||||||
<p>Пн</p>
|
<p>Понедельник</p>
|
||||||
<p>Вт</p>
|
<p>Вторник</p>
|
||||||
<p>Ср</p>
|
<p>Среда</p>
|
||||||
<p>Чт</p>
|
<p>Четверг</p>
|
||||||
<p>Пт</p>
|
<p>Пятница</p>
|
||||||
<p>Сб</p>
|
<p>Суббота</p>
|
||||||
<p>Вс</p>
|
<p>Воскресенье</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="calendar-component__form">
|
<div className="calendar-component__form">
|
||||||
@ -260,12 +266,12 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
id="btn"
|
id="btn"
|
||||||
>
|
>
|
||||||
<Link to={startRangeDays ? "#" : correctRoute(day)}>
|
<Link to={startRangeDays ? "#" : correctRoute(day)}>
|
||||||
<img
|
<div className="form-date">{day.format("D")}</div>
|
||||||
className={"calendar__icon"}
|
<div className="form-box">
|
||||||
src={calendarIcon}
|
<div className="form-hours">
|
||||||
alt=""
|
<span>{countHours(day)}</span>
|
||||||
/>
|
</div>
|
||||||
{currentMonthAndDay(day)}
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</button>
|
</button>
|
||||||
))
|
))
|
||||||
@ -289,6 +295,7 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
? "Выберите диапазон на календаре"
|
? "Выберите диапазон на календаре"
|
||||||
: "Выбрать диапазон"}
|
: "Выбрать диапазон"}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{totalRangeHours
|
{totalRangeHours
|
||||||
? `${totalRangeHours} ${hourOfNum(totalRangeHours)}`
|
? `${totalRangeHours} ${hourOfNum(totalRangeHours)}`
|
||||||
@ -308,6 +315,7 @@ export const ProfileCalendarComponent = React.memo(
|
|||||||
Сбросить
|
Сбросить
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
)}
|
)}
|
||||||
|
<span className="hint">Для общего просчета - выберите диапазон</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
@ -23,6 +22,25 @@
|
|||||||
@media (max-width: 500px) {
|
@media (max-width: 500px) {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.summary__skill {
|
||||||
|
color: #6f6f6f;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 300;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 10px;
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
border: #8dc63f 0.5px solid;
|
||||||
|
border-radius: 44px;
|
||||||
|
padding: 3px 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.loader__wrapper {
|
.loader__wrapper {
|
||||||
@ -37,7 +55,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.calendar__wrapper {
|
.calendar__wrapper {
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,82 @@ import { NavLink, useNavigate } from "react-router-dom";
|
|||||||
|
|
||||||
import { auth, getProfileInfo, setProfileInfo } from "@redux/outstaffingSlice";
|
import { auth, getProfileInfo, setProfileInfo } from "@redux/outstaffingSlice";
|
||||||
|
|
||||||
|
import { urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
|
|
||||||
|
import avatarMok from "assets/images/avatarMok.png";
|
||||||
|
|
||||||
import "./profileHeader.scss";
|
import "./profileHeader.scss";
|
||||||
|
|
||||||
export const ProfileHeader = () => {
|
export const ProfileHeader = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const profileInfo = useSelector(getProfileInfo);
|
const profileInfo = useSelector(getProfileInfo);
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
const [user] = useState(
|
const [user] = useState(
|
||||||
localStorage.getItem("role_status") === "18" ? "partner" : "developer"
|
localStorage.getItem("role_status") === "18" ? "partner" : "developer"
|
||||||
);
|
);
|
||||||
|
|
||||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||||
|
|
||||||
|
const [navInfo] = useState({
|
||||||
|
developer: [
|
||||||
|
{
|
||||||
|
path: "/summary",
|
||||||
|
name: "Резюме"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/calendar",
|
||||||
|
name: "Отчеты"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/tracker",
|
||||||
|
name: "Трекер"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// path: "/payouts",
|
||||||
|
// name: "Выплаты"
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
path: "/quiz",
|
||||||
|
name: "Тесты"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/settings",
|
||||||
|
name: "Настройки"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
partner: [
|
||||||
|
{
|
||||||
|
path: "/catalog",
|
||||||
|
name: "Каталог"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/requests",
|
||||||
|
name: "Мои вакансии"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/employees",
|
||||||
|
name: "Персонал"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/tracker",
|
||||||
|
name: "Трекер"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// path: "/treaties",
|
||||||
|
// name: "Договоры"
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
path: "/settings",
|
||||||
|
name: "Настройки"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!Object.keys(profileInfo).length)
|
if (!Object.keys(profileInfo).length)
|
||||||
apiRequest(`/user/me`).then((profileInfo) => {
|
apiRequest(`/user/me`).then((profileInfo) => {
|
||||||
@ -31,30 +91,95 @@ export const ProfileHeader = () => {
|
|||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handler = () => {
|
const handler = (e) => {
|
||||||
setIsLoggingOut(true);
|
e.preventDefault();
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
dispatch(auth(false));
|
dispatch(auth(false));
|
||||||
setIsLoggingOut(false);
|
|
||||||
navigate("/auth");
|
navigate("/auth");
|
||||||
dispatch(setProfileInfo({}));
|
dispatch(setProfileInfo({}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [active, setActive] = useState(false);
|
||||||
|
|
||||||
|
const toggleBar = () => {
|
||||||
|
if (active) {
|
||||||
|
setActive(false);
|
||||||
|
} else {
|
||||||
|
setActive(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeMenu = () => {
|
||||||
|
setActive(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="profile-header">
|
<header className="profile-header">
|
||||||
<div className="profile-header__head">
|
<div className="auth-title">
|
||||||
<div className="profile-header__container">
|
<div className="text">
|
||||||
<NavLink to={"/profile"} className="profile-header__title">
|
<NavLink to={"/profile"} className="profile-header__title">
|
||||||
itguild.
|
itguild.
|
||||||
<span>
|
<span>
|
||||||
{user === "developer" ? "для разработчиков" : "для партнеров"}
|
{user === "developer" ? "для разработчиков" : "для партнеров"}
|
||||||
</span>
|
</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
|
||||||
<button onClick={handler} className="profile-header__logout">
|
<button onClick={handler} className="profile-header__logout">
|
||||||
{isLoggingOut ? <Loader /> : "Выйти"}
|
{isLoggingOut ? <Loader /> : "Выйти"}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<div className="burger" onClick={() => toggleBar()}>
|
||||||
|
<div
|
||||||
|
className={active ? "burger__line l1 change" : "burger__line"}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className={active ? "burger__line l2 change" : "burger__line"}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className={active ? "burger__line l3 change" : "burger__line"}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={active ? "auth-body active" : "auth-body"}>
|
||||||
|
<nav className="auth-body__navigation">
|
||||||
|
<div className="profile-header__personal-info">
|
||||||
|
<h3 className="profile-header__personal-info-name">
|
||||||
|
{profileInfo?.fio || profileInfo?.username}
|
||||||
|
</h3>
|
||||||
|
<NavLink end to={"/profile"}>
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
profileInfo?.photo
|
||||||
|
? urlForLocal(profileInfo.photo)
|
||||||
|
: avatarMok
|
||||||
|
}
|
||||||
|
className="profile-header__personal-info-avatar"
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{navInfo[user].map((link, index) => {
|
||||||
|
return (
|
||||||
|
<NavLink
|
||||||
|
key={index}
|
||||||
|
end
|
||||||
|
to={link.path === "/quiz" ? link.path : `/profile${link.path}`}
|
||||||
|
className={currentPath.includes(link.path) ? "active" : ""}
|
||||||
|
>
|
||||||
|
{link.name}
|
||||||
|
</NavLink>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<button onClick={handler} className="profile-header__logout-burger">
|
||||||
|
{isLoggingOut ? <Loader /> : "Выйти"}
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
{active && <div className="backdrop" onClick={closeMenu}></div>}
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,156 @@
|
|||||||
.profile-header {
|
.profile-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 66px;
|
||||||
|
background: #e1fccf;
|
||||||
|
padding: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
|
|
||||||
&__head {
|
&__head {
|
||||||
background: #e1fccf;
|
background: #e1fccf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auth-title {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 1160px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 15px;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.burger {
|
||||||
|
display: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@media (max-width: 414px) {
|
||||||
|
display: block;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__line {
|
||||||
|
width: 32px;
|
||||||
|
border-radius: 33px;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #333;
|
||||||
|
margin: 5px 0 0 27px;
|
||||||
|
transition: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.l1.change {
|
||||||
|
transform: rotate(-45deg) translate(-7px, 6px);
|
||||||
|
}
|
||||||
|
.l2.change {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.l3.change {
|
||||||
|
transform: rotate(45deg) translate(-8px, -8px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.backdrop {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-body {
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 8;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #e1fccf;
|
||||||
|
transition: 0.3s;
|
||||||
|
|
||||||
|
// @media (max-width: 414px) {
|
||||||
|
// display: block;
|
||||||
|
// }
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 24px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__navigation {
|
||||||
|
margin-top: 28px;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: 15px 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
a:hover,
|
||||||
|
a:active {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__politic {
|
||||||
|
margin-top: 42px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__contacts {
|
||||||
|
margin-top: 127px;
|
||||||
|
color: #000000;
|
||||||
|
h4 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 33px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-body.active {
|
||||||
|
padding: 40px 10px;
|
||||||
|
opacity: 1;
|
||||||
|
display: flex;
|
||||||
|
overflow: visible;
|
||||||
|
width: calc(100vw / 2.5);
|
||||||
|
transition: width 0.3s;
|
||||||
|
height: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
@ -15,7 +158,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 50px;
|
min-height: 66px;
|
||||||
|
|
||||||
|
@media (max-width: 414px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
@ -42,10 +189,20 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
|
||||||
|
@media (max-width: 414px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__info {
|
&__logout-burger {
|
||||||
background: #ffffff;
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 15px 0 0 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 32px;
|
||||||
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__nav {
|
&__nav {
|
||||||
@ -69,6 +226,7 @@
|
|||||||
|
|
||||||
a.active {
|
a.active {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
@ -87,7 +245,10 @@
|
|||||||
&__personal-info {
|
&__personal-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
column-gap: 20px;
|
column-gap: 20px;
|
||||||
|
flex-direction: row-reverse;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
&-name {
|
&-name {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
@ -103,6 +264,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.active {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&-avatar {
|
&-avatar {
|
||||||
width: 37px;
|
width: 37px;
|
||||||
height: 37px;
|
height: 37px;
|
||||||
|
@ -68,6 +68,11 @@ export const ProjectTicket = ({ project, index }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// showNotification({
|
||||||
|
// show: true,
|
||||||
|
// text: "Проект успешно удален",
|
||||||
|
// type: "success"
|
||||||
|
// });
|
||||||
|
|
||||||
function closeAcceptModal() {
|
function closeAcceptModal() {
|
||||||
setAcceptModalOpen(false);
|
setAcceptModalOpen(false);
|
||||||
@ -96,16 +101,16 @@ export const ProjectTicket = ({ project, index }) => {
|
|||||||
alt="avatar"
|
alt="avatar"
|
||||||
className="project__avatar"
|
className="project__avatar"
|
||||||
/>
|
/>
|
||||||
|
<div>
|
||||||
|
<p>Создатель проекта</p>
|
||||||
<span>{project.owner_info.fio}</span>
|
<span>{project.owner_info.fio}</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
{/* <Link
|
<Link to={`/profile/statistics/${project.id}`} className="project-stats">
|
||||||
to={`/profile/statistics/${project.id}`}
|
|
||||||
className="project__statistics"
|
|
||||||
>
|
|
||||||
Посмотреть статистику
|
Посмотреть статистику
|
||||||
</Link> */}
|
</Link>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
className="menu-settings"
|
className="menu-settings"
|
||||||
@ -135,7 +140,16 @@ export const ProjectTicket = ({ project, index }) => {
|
|||||||
<img src={edit}></img>
|
<img src={edit}></img>
|
||||||
<p>редактировать</p>
|
<p>редактировать</p>
|
||||||
</div>
|
</div>
|
||||||
<div onClick={copyProjectLink(project.id)}>
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
copyProjectLink(project.id);
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Ссылка скопирована в буфер обмена",
|
||||||
|
type: "copy"
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
<img src={link}></img>
|
<img src={link}></img>
|
||||||
<p>скопировать ссылку</p>
|
<p>скопировать ссылку</p>
|
||||||
</div>
|
</div>
|
||||||
@ -145,14 +159,14 @@ export const ProjectTicket = ({ project, index }) => {
|
|||||||
setAcceptModalOpen(true);
|
setAcceptModalOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img src={archiveSet}></img>
|
{/* <img src={archiveSet}></img>
|
||||||
<p>в архив</p>
|
<p>в архив</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(`/profile/statistics/${project.id}`);
|
navigate(`/profile/statistics/${project.id}`);
|
||||||
}}
|
}}
|
||||||
>
|
> */}
|
||||||
<img src={archiveSet}></img>
|
<img src={archiveSet}></img>
|
||||||
<p>статистика</p>
|
<p>статистика</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 300px;
|
width: 22%;
|
||||||
|
height: 140px;
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: #111112;
|
color: #111112;
|
||||||
margin-bottom: 10px;
|
margin: 0 0 15px 0;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: black;
|
color: black;
|
||||||
@ -44,14 +45,15 @@
|
|||||||
p {
|
p {
|
||||||
color: #6f6f6f;
|
color: #6f6f6f;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
font-size: 12px;
|
font-size: 9px;
|
||||||
font-weight: 500;
|
font-weight: 300;
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: blue;
|
color: blue;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.count {
|
.count {
|
||||||
@ -80,18 +82,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-stats {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: 17px;
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #678eda;
|
||||||
|
position: absolute;
|
||||||
|
left: 18px;
|
||||||
|
bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-settings {
|
.menu-settings {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
color: #6f6f6f;
|
color: #6f6f6f;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
top: -10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__avatar {
|
&__avatar {
|
||||||
width: 25px;
|
width: 30px;
|
||||||
height: 25px;
|
height: 30px;
|
||||||
margin-right: 10px;
|
margin: 0 10px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__open-tracker {
|
&__open-tracker {
|
||||||
|
@ -18,6 +18,7 @@ import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadc
|
|||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
|
|
||||||
import arrow from "assets/icons/arrows/left-arrow.png";
|
import arrow from "assets/icons/arrows/left-arrow.png";
|
||||||
|
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
||||||
import calendarIcon from "assets/icons/calendar.svg";
|
import calendarIcon from "assets/icons/calendar.svg";
|
||||||
import ellipse from "assets/icons/ellipse.png";
|
import ellipse from "assets/icons/ellipse.png";
|
||||||
import remove from "assets/icons/remove.svg";
|
import remove from "assets/icons/remove.svg";
|
||||||
@ -26,12 +27,12 @@ import {
|
|||||||
getCorrectDate,
|
getCorrectDate,
|
||||||
getCreatedDate,
|
getCreatedDate,
|
||||||
hourOfNum
|
hourOfNum
|
||||||
} from "../Calendar/calendarHelper";
|
} from "../../utils/calendarHelper";
|
||||||
import "./reportForm.scss";
|
import "./reportForm.scss";
|
||||||
|
|
||||||
registerLocale("ru", ru);
|
registerLocale("ru", ru);
|
||||||
|
|
||||||
const ReportForm = () => {
|
export const ReportForm = () => {
|
||||||
if (localStorage.getItem("role_status") === "18") {
|
if (localStorage.getItem("role_status") === "18") {
|
||||||
return <Navigate to="/profile" replace />;
|
return <Navigate to="/profile" replace />;
|
||||||
}
|
}
|
||||||
@ -42,6 +43,7 @@ const ReportForm = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initListeners();
|
initListeners();
|
||||||
|
getProjectList();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
const [isFetching, setIsFetching] = useState(false);
|
||||||
@ -51,6 +53,10 @@ const ReportForm = () => {
|
|||||||
? new Date(reportDate ? reportDate._d : editReport.created_at)
|
? new Date(reportDate ? reportDate._d : editReport.created_at)
|
||||||
: new Date()
|
: new Date()
|
||||||
);
|
);
|
||||||
|
const [projectList, setProjectList] = useState([]);
|
||||||
|
const [projectLoader, setProjectLoader] = useState(false);
|
||||||
|
const [selectedProject, setSelectedProject] = useState("Выберите проект");
|
||||||
|
const [openSelectProject, setOpenSelectProject] = useState(false);
|
||||||
const [datePickerOpen, setDatePickerOpen] = useState(false);
|
const [datePickerOpen, setDatePickerOpen] = useState(false);
|
||||||
|
|
||||||
const [inputs, setInputs] = useState(
|
const [inputs, setInputs] = useState(
|
||||||
@ -85,10 +91,12 @@ const ReportForm = () => {
|
|||||||
(div) =>
|
(div) =>
|
||||||
div.classList &&
|
div.classList &&
|
||||||
(div.classList.contains("report-form__block-img") ||
|
(div.classList.contains("report-form__block-img") ||
|
||||||
div.classList.contains("react-datepicker-popper"))
|
div.classList.contains("react-datepicker-popper") ||
|
||||||
|
div.classList.contains("report-form__project"))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
setDatePickerOpen(false);
|
setDatePickerOpen(false);
|
||||||
|
setOpenSelectProject(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,6 +106,17 @@ const ReportForm = () => {
|
|||||||
setInputs((prev) => prev.filter((el, index) => index !== indexRemove));
|
setInputs((prev) => prev.filter((el, index) => index !== indexRemove));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getProjectList = () => {
|
||||||
|
setProjectLoader(true);
|
||||||
|
apiRequest(
|
||||||
|
`/project/project-list?user_id=${localStorage.getItem(
|
||||||
|
"id"
|
||||||
|
)}&expand=columns`
|
||||||
|
).then((el) => {
|
||||||
|
setProjectLoader(false);
|
||||||
|
setProjectList(el?.projects);
|
||||||
|
});
|
||||||
|
};
|
||||||
const handler = () => {
|
const handler = () => {
|
||||||
setIsFetching(true);
|
setIsFetching(true);
|
||||||
for (let input of inputs) {
|
for (let input of inputs) {
|
||||||
@ -113,6 +132,7 @@ const ReportForm = () => {
|
|||||||
data: {
|
data: {
|
||||||
user_id: localStorage.getItem("id"),
|
user_id: localStorage.getItem("id"),
|
||||||
tasks: inputs,
|
tasks: inputs,
|
||||||
|
project_id: selectedProject.id ? selectedProject.id : "",
|
||||||
difficulties: troublesInputValue,
|
difficulties: troublesInputValue,
|
||||||
tomorrow: scheduledInputValue,
|
tomorrow: scheduledInputValue,
|
||||||
created_at: getCreatedDate(startDate),
|
created_at: getCreatedDate(startDate),
|
||||||
@ -144,6 +164,7 @@ const ReportForm = () => {
|
|||||||
data: {
|
data: {
|
||||||
tasks: inputs,
|
tasks: inputs,
|
||||||
difficulties: troublesInputValue,
|
difficulties: troublesInputValue,
|
||||||
|
project_id: selectedProject.id ? selectedProject.id : "",
|
||||||
tomorrow: scheduledInputValue,
|
tomorrow: scheduledInputValue,
|
||||||
created_at: getCreatedDate(startDate),
|
created_at: getCreatedDate(startDate),
|
||||||
status: 1
|
status: 1
|
||||||
@ -220,6 +241,58 @@ const ReportForm = () => {
|
|||||||
setStartDate(date);
|
setStartDate(date);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{projectLoader ? (
|
||||||
|
<div className="loader__wrapper">
|
||||||
|
<Loader />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="report-form__task-list">
|
||||||
|
<img src={ellipse} alt="" />
|
||||||
|
<span>Выберите проект</span>
|
||||||
|
</div>
|
||||||
|
<div className="report-form__project">
|
||||||
|
<div
|
||||||
|
className="project__selected"
|
||||||
|
onClick={() => setOpenSelectProject(!openSelectProject)}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{selectedProject.name
|
||||||
|
? selectedProject.name
|
||||||
|
: selectedProject}
|
||||||
|
</p>
|
||||||
|
<img
|
||||||
|
className={
|
||||||
|
openSelectProject ? "project__selected--open" : ""
|
||||||
|
}
|
||||||
|
src={arrowDown}
|
||||||
|
alt="arrow"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{openSelectProject && (
|
||||||
|
<div className="project__dropDown">
|
||||||
|
{Boolean(projectList.length) ? (
|
||||||
|
projectList.map((project) => {
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedProject(project);
|
||||||
|
setOpenSelectProject(false);
|
||||||
|
}}
|
||||||
|
key={project.id}
|
||||||
|
>
|
||||||
|
{project.name}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<span>Проектов нет</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<div className="report-form__task-list">
|
<div className="report-form__task-list">
|
||||||
<img src={ellipse} alt="" />
|
<img src={ellipse} alt="" />
|
||||||
<span>Какие задачи выполнены?</span>
|
<span>Какие задачи выполнены?</span>
|
||||||
@ -383,5 +456,3 @@ const ReportForm = () => {
|
|||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ReportForm;
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
.report-form {
|
.report-form {
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
margin-top: 23px;
|
margin-top: 23px;
|
||||||
|
|
||||||
@ -29,11 +34,15 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-column-gap: 30px;
|
grid-column-gap: 30px;
|
||||||
column-gap: 30px;
|
column-gap: 10px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -102,6 +111,62 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loader__wrapper {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__project {
|
||||||
|
position: relative;
|
||||||
|
max-width: 200px;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.project {
|
||||||
|
&__selected {
|
||||||
|
display: flex;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 5px;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--open {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dropDown {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #c2c2c2;
|
||||||
|
padding: 5px;
|
||||||
|
z-index: 100;
|
||||||
|
row-gap: 3px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__task {
|
&__task {
|
||||||
&-number {
|
&-number {
|
||||||
color: #282828;
|
color: #282828;
|
||||||
@ -428,7 +493,6 @@
|
|||||||
|
|
||||||
.react-datepicker__current-month {
|
.react-datepicker__current-month {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,13 +504,11 @@
|
|||||||
.react-datepicker__day {
|
.react-datepicker__day {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-datepicker__day-name {
|
.react-datepicker__day-name {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
font-family: "LabGrotesque", sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.react-datepicker__triangle {
|
.react-datepicker__triangle {
|
||||||
|
@ -8,13 +8,14 @@ import {
|
|||||||
setSendRequest
|
setSendRequest
|
||||||
} from "@redux/reportSlice";
|
} from "@redux/reportSlice";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getCorrectDate,
|
getCorrectDate,
|
||||||
getCreatedDate,
|
getCreatedDate,
|
||||||
hourOfNum
|
hourOfNum
|
||||||
} from "@components/Calendar/calendarHelper";
|
} from "@utils/calendarHelper";
|
||||||
|
|
||||||
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { Loader } from "@components/Common/Loader/Loader";
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
|
|
||||||
import "./shortReport.scss";
|
import "./shortReport.scss";
|
||||||
|
@ -47,23 +47,23 @@ export const SideBar = () => {
|
|||||||
</div>
|
</div>
|
||||||
<ul className="auth-body__navigation">
|
<ul className="auth-body__navigation">
|
||||||
<li>
|
<li>
|
||||||
<Link to={"/auth"}>Вход для партнеров</Link>
|
<Link to={"/auth"}>Вход</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to={"/auth"}>Кабинет разработчика</Link>
|
<Link to={"/profile"}>Личный кабинет</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to={"/tracker-intro"}>Трекер</Link>
|
<Link to={"/tracker-intro"}>Трекер</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link to={"/Quiz"}>Тесты</Link>
|
<Link to={"/quiz"}>Тесты</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link to={"/forms"}>Формы</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="#">Школа</a>
|
<a href="#">Школа</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a href="#">Отрасли</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
<li>
|
||||||
<a href="#">Контакты</a>
|
<a href="#">Контакты</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
@media (max-width: 1440px) {
|
@media (max-width: 1440px) {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.auth-title {
|
.auth-title {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -197,3 +196,4 @@
|
|||||||
height: 705px;
|
height: 705px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
193
src/components/TrackerCardTask/TrackerCardTask.jsx
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
|
import { movePositionProjectTask } from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
|
import { removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
|
import TrackerSelectColumn from "@components/TrackerSelectColumn/TrackerSelectColumn";
|
||||||
|
|
||||||
|
import commentsBoard from "assets/icons/commentsBoard.svg";
|
||||||
|
import filesBoard from "assets/icons/filesBoard.svg";
|
||||||
|
import avatarMok from "assets/images/avatarMok.png";
|
||||||
|
|
||||||
|
import "./trackerCardTask.scss";
|
||||||
|
|
||||||
|
const TrackerCardTask = ({
|
||||||
|
task,
|
||||||
|
projectBoard,
|
||||||
|
titleColor,
|
||||||
|
column,
|
||||||
|
openTicket,
|
||||||
|
startWrapperIndexTest,
|
||||||
|
setWrapperHover
|
||||||
|
}) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const [taskHover, setTaskHover] = useState({});
|
||||||
|
|
||||||
|
const priority = {
|
||||||
|
2: "Высокий",
|
||||||
|
1: "Средний",
|
||||||
|
0: "Низкий"
|
||||||
|
};
|
||||||
|
|
||||||
|
const priorityClass = {
|
||||||
|
2: "high",
|
||||||
|
1: "middle",
|
||||||
|
0: "low"
|
||||||
|
};
|
||||||
|
|
||||||
|
function dragDropTaskHandler(e, task, column) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (task.id === startWrapperIndexTest.current.task.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const finishTask = column.tasks.indexOf(task);
|
||||||
|
|
||||||
|
dispatch(
|
||||||
|
movePositionProjectTask({
|
||||||
|
startTask: startWrapperIndexTest.current.task,
|
||||||
|
finishTask: task,
|
||||||
|
finishIndex: finishTask
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragOverTaskHandler(e, task) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (startWrapperIndexTest.current.task.id === task.id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTaskHover((prevState) => ({ [prevState]: false, [task.id]: true }));
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragStartHandler(e, task, columnId) {
|
||||||
|
startWrapperIndexTest.current = { task: task, index: columnId };
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragLeaveTaskHandler() {
|
||||||
|
setTaskHover((prevState) => ({ [prevState]: false }));
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragEndTaskHandler() {
|
||||||
|
setTaskHover((prevState) => ({ [prevState]: false }));
|
||||||
|
setWrapperHover((prevState) => ({
|
||||||
|
[prevState]: false
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const tasksHover = {};
|
||||||
|
const columnHover = {};
|
||||||
|
|
||||||
|
if (Object.keys(projectBoard).length) {
|
||||||
|
projectBoard.columns.forEach((column) => {
|
||||||
|
columnHover[column.id] = false;
|
||||||
|
column.tasks.forEach((task) => (tasksHover[task.id] = false));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setWrapperHover(columnHover);
|
||||||
|
setTaskHover(tasksHover);
|
||||||
|
}, [projectBoard]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={task.id}
|
||||||
|
className={`tasks__board__item ${
|
||||||
|
taskHover[task.id] ? "task__hover" : ""
|
||||||
|
}`}
|
||||||
|
draggable={true}
|
||||||
|
onDragStart={(e) => dragStartHandler(e, task, column.id)}
|
||||||
|
onDragOver={(e) => dragOverTaskHandler(e, task)}
|
||||||
|
onDragLeave={(e) => dragLeaveTaskHandler(e)}
|
||||||
|
onDragEnd={() => dragEndTaskHandler()}
|
||||||
|
onDrop={(e) => dragDropTaskHandler(e, task, column)}
|
||||||
|
onClick={(e) => openTicket(e, task)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="tasks__board__item__title"
|
||||||
|
onClick={() => {
|
||||||
|
if (window.innerWidth < 985) {
|
||||||
|
window.location.replace(`/tracker/task/${task.id}`);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p className="task__board__item__title">{task.title}</p>
|
||||||
|
</div>
|
||||||
|
<p
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: task.description
|
||||||
|
}}
|
||||||
|
className="tasks__board__item__description"
|
||||||
|
></p>
|
||||||
|
{Boolean(task.mark.length) && (
|
||||||
|
<div className="tasks__board__item__tags">
|
||||||
|
{task.mark.map((tag) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="tag-item"
|
||||||
|
key={tag.id}
|
||||||
|
style={{ background: tag.color }}
|
||||||
|
>
|
||||||
|
<p>{tag.slug}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="tasks__board__item__container">
|
||||||
|
{typeof task.execution_priority === "number" && (
|
||||||
|
<div className="tasks__board__item__priority">
|
||||||
|
<p>⚡</p>
|
||||||
|
<span className={priorityClass[task.execution_priority]}>
|
||||||
|
{priority[task.execution_priority]}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{task.dead_line && (
|
||||||
|
<div className="tasks__board__item__dead-line">
|
||||||
|
<p>⌛</p>
|
||||||
|
<span style={{ color: titleColor }}>
|
||||||
|
{getCorrectDate(task.dead_line)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="tasks__board__item__info">
|
||||||
|
<div className="tasks__board__item__executor">
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
task.executor?.avatar
|
||||||
|
? urlForLocal(task.executor?.avatar)
|
||||||
|
: avatarMok
|
||||||
|
}
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
{removeLast(task.executor?.fio) || "Исполнитель не назначен"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="tasks__board__item__info__tags">
|
||||||
|
<div className="tasks__board__item__info__more">
|
||||||
|
<img src={commentsBoard} alt="commentsImg" />
|
||||||
|
<span>{task.comment_count}</span>
|
||||||
|
</div>
|
||||||
|
<div className="tasks__board__item__info__more">
|
||||||
|
<img src={filesBoard} alt="filesImg" />
|
||||||
|
<span>{task.file_count}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<TrackerSelectColumn
|
||||||
|
columns={projectBoard.columns.filter((item) => item.id !== column.id)}
|
||||||
|
currentColumn={column}
|
||||||
|
task={task}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrackerCardTask;
|
365
src/components/TrackerCardTask/trackerCardTask.scss
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
.tasks {
|
||||||
|
&__board {
|
||||||
|
background: #f5f7f9;
|
||||||
|
box-shadow: 0px 2px 5px rgba(60, 66, 87, 0.04),
|
||||||
|
0px 0px 0px 1px rgba(60, 66, 87, 0.08), 0px 1px 1px rgba(0, 0, 0, 0.06);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px 10px 12px 8px;
|
||||||
|
width: 360px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 10px;
|
||||||
|
height: fit-content;
|
||||||
|
position: relative;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
transform: scaleY(-1);
|
||||||
|
min-height: 815px;
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
min-width: auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tasks-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 8px;
|
||||||
|
max-height: 750px;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #cbd9f9;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #c5c0c6;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__hover {
|
||||||
|
box-shadow: 0px 2px 10px #9cc480, 0px 0px 0px 1px rgba(60, 66, 87, 0.08),
|
||||||
|
0px 1px 1px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.task__hover {
|
||||||
|
box-shadow: 0 0 5px gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
width: 328px;
|
||||||
|
padding: 6px 10px 8px 10px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0px 3px 2px -2px rgba(0, 0, 0, 0.06),
|
||||||
|
0px 5px 3px -2px rgba(0, 0, 0, 0.02);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #ffffff;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
transition: 0.4s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.025);
|
||||||
|
transition: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
width: 100%;
|
||||||
|
max-height: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__hide {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #1a1919;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
max-height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
border-radius: 6px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 20px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
margin: 4px 0;
|
||||||
|
color: #5c6165;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 120%;
|
||||||
|
max-height: 100px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
pointer-events: none;
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
&__tags {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__more {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
span {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 15px;
|
||||||
|
color: #6e7c87;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__avatars {
|
||||||
|
position: relative;
|
||||||
|
img {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
img:first-child {
|
||||||
|
right: -15px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__priority {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 5px;
|
||||||
|
margin-top: 3px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle {
|
||||||
|
color: #cece00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.low {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dead-line {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 5px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1458dd;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-top: -2px;
|
||||||
|
width: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__executor {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
column-gap: 5px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
max-width: 210px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
column-gap: 6px;
|
||||||
|
row-gap: 3px;
|
||||||
|
margin: 3px 0;
|
||||||
|
|
||||||
|
.tag-item {
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: white;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-items {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 44px;
|
||||||
|
width: 33px;
|
||||||
|
height: 33px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -15px;
|
||||||
|
font-size: 20px;
|
||||||
|
left: 165px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-items {
|
||||||
|
background: #8bcc60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.less-items {
|
||||||
|
background: #f92828;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__more {
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column__select {
|
||||||
|
position: absolute;
|
||||||
|
padding: 15px;
|
||||||
|
background: #e1fccf;
|
||||||
|
border-radius: 12px;
|
||||||
|
right: -20px;
|
||||||
|
top: 5px;
|
||||||
|
z-index: 7;
|
||||||
|
row-gap: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
@media (max-width: 910px) {
|
||||||
|
right: 10px;
|
||||||
|
top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
img {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__no-items {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 25px;
|
||||||
|
transform: scaleY(-1);
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__no-tasks {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
transform: scaleY(-1);
|
||||||
|
|
||||||
|
&-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
img {
|
||||||
|
width: 27px;
|
||||||
|
height: 27px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-more {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
113
src/components/TrackerSelectExecutor/TrackerSelectExecutor.jsx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
|
||||||
|
import { filteredExecutorTasks } from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
|
import { removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
|
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
||||||
|
import close from "assets/icons/close.png";
|
||||||
|
import avatarMok from "assets/images/avatarMok.png";
|
||||||
|
|
||||||
|
import "./trackerSelectExecutor.scss";
|
||||||
|
|
||||||
|
const TrackerSelectExecutor = ({
|
||||||
|
selectedExecutor,
|
||||||
|
setSelectedExecutor,
|
||||||
|
deleteSelectedExecutor,
|
||||||
|
projectBoard
|
||||||
|
}) => {
|
||||||
|
const [selectExecutorOpen, setSelectedExecutorOpen] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const initListeners = () => {
|
||||||
|
document.addEventListener("click", closeByClickingOut);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeByClickingOut = (event) => {
|
||||||
|
const path = event.path || (event.composedPath && event.composedPath());
|
||||||
|
|
||||||
|
if (
|
||||||
|
event &&
|
||||||
|
!path.find(
|
||||||
|
(div) =>
|
||||||
|
div.classList &&
|
||||||
|
(div.classList.contains("tasks__head__executor") ||
|
||||||
|
div.classList.contains("tasks__head__executor-dropdown"))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setSelectedExecutorOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function executorFilter(user) {
|
||||||
|
dispatch(filteredExecutorTasks(user.user_id));
|
||||||
|
setSelectedExecutor(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initListeners();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (selectedExecutor) {
|
||||||
|
return (
|
||||||
|
<div className="tasks__head__executor-selected">
|
||||||
|
<p>{removeLast(selectedExecutor.user.fio)}</p>
|
||||||
|
<img
|
||||||
|
className="avatar"
|
||||||
|
src={
|
||||||
|
selectedExecutor.user?.avatar
|
||||||
|
? urlForLocal(selectedExecutor.user.avatar)
|
||||||
|
: avatarMok
|
||||||
|
}
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
className="delete"
|
||||||
|
src={close}
|
||||||
|
alt="delete"
|
||||||
|
onClick={deleteSelectedExecutor}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="tasks__head__executor"
|
||||||
|
onClick={() => setSelectedExecutorOpen(!selectExecutorOpen)}
|
||||||
|
>
|
||||||
|
<p>Выберите исполнителя</p>
|
||||||
|
<img
|
||||||
|
className={selectExecutorOpen ? "open" : ""}
|
||||||
|
src={arrowDown}
|
||||||
|
alt="arrow"
|
||||||
|
/>
|
||||||
|
{selectExecutorOpen && (
|
||||||
|
<div className="tasks__head__executor-dropdown">
|
||||||
|
{projectBoard.projectUsers.map((user) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="executor-dropdown__person"
|
||||||
|
key={user.user_id}
|
||||||
|
onClick={() => executorFilter(user)}
|
||||||
|
>
|
||||||
|
<p>{removeLast(user.user?.fio)}</p>
|
||||||
|
<img
|
||||||
|
src={
|
||||||
|
user.user?.avatar
|
||||||
|
? urlForLocal(user.user.avatar)
|
||||||
|
: avatarMok
|
||||||
|
}
|
||||||
|
alt="avatar"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrackerSelectExecutor;
|
129
src/components/TrackerSelectExecutor/trackerSelectExecutor.scss
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
.tasks {
|
||||||
|
&__head {
|
||||||
|
&__executor {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e3e2e2;
|
||||||
|
padding: 2px 6px;
|
||||||
|
position: relative;
|
||||||
|
max-width: 190px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (max-width: 915px) {
|
||||||
|
margin-right: 0;
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 650px) {
|
||||||
|
border-color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-selected {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 8px;
|
||||||
|
max-width: 220px;
|
||||||
|
width: 100%;
|
||||||
|
margin-right: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #252c32;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
max-width: 155px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: flex;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 915px) {
|
||||||
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
|
justify-content: start;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 16px;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #252c32;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: 33px;
|
||||||
|
left: 0;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
z-index: 5;
|
||||||
|
padding: 10px 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 7px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.executor-dropdown__person {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
p {
|
||||||
|
max-width: 155px;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
@media (max-width: 915px) {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
p {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
275
src/components/TrackerTagList/TrackerTagList.jsx
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { HexColorPicker } from "react-colorful";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
import {
|
||||||
|
addNewTagToProject,
|
||||||
|
deleteTagProject,
|
||||||
|
setProjectBoardFetch
|
||||||
|
} from "@redux/projectsTrackerSlice";
|
||||||
|
|
||||||
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
|
import arrowDown from "assets/icons/arrows/selectArrow.png";
|
||||||
|
import close from "assets/icons/close.png";
|
||||||
|
import edit from "assets/icons/edit.svg";
|
||||||
|
|
||||||
|
import "./trackerTagList.scss";
|
||||||
|
|
||||||
|
const TrackerTagList = ({ projectBoard }) => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const projectId = useParams();
|
||||||
|
|
||||||
|
const { showNotification } = useNotification();
|
||||||
|
const [tagInfo, setTagInfo] = useState({ description: "", name: "" });
|
||||||
|
const [color, setColor] = useState("#aabbcc");
|
||||||
|
const [tags, setTags] = useState({
|
||||||
|
open: false,
|
||||||
|
add: false,
|
||||||
|
edit: false
|
||||||
|
});
|
||||||
|
|
||||||
|
function deleteTag(tagId) {
|
||||||
|
apiRequest("/mark/detach", {
|
||||||
|
method: "DELETE",
|
||||||
|
data: {
|
||||||
|
mark_id: tagId,
|
||||||
|
entity_type: 1,
|
||||||
|
entity_id: projectId.id
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
dispatch(deleteTagProject(tagId));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Тег удален",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addNewTag() {
|
||||||
|
apiRequest("/mark/create", {
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
title: tagInfo.description,
|
||||||
|
slug: tagInfo.name,
|
||||||
|
color: color,
|
||||||
|
status: 1
|
||||||
|
}
|
||||||
|
}).then((data) => {
|
||||||
|
apiRequest("/mark/attach", {
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
mark_id: data.id,
|
||||||
|
entity_type: 1,
|
||||||
|
entity_id: projectId.id
|
||||||
|
}
|
||||||
|
}).then((data) => {
|
||||||
|
dispatch(addNewTagToProject(data.mark));
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
add: false
|
||||||
|
}));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Тег успешно создан",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function editTag() {
|
||||||
|
apiRequest("/mark/update", {
|
||||||
|
method: "PUT",
|
||||||
|
data: {
|
||||||
|
mark_id: tagInfo.editMarkId,
|
||||||
|
title: tagInfo.description,
|
||||||
|
slug: tagInfo.name,
|
||||||
|
color: color
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
dispatch(setProjectBoardFetch(projectId.id));
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
edit: false
|
||||||
|
}));
|
||||||
|
setTagInfo({ description: "", name: "" });
|
||||||
|
setColor("#aabbcc");
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Тег успешно изменён",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const initListeners = () => {
|
||||||
|
document.addEventListener("click", closeByClickingOut);
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeByClickingOut = (event) => {
|
||||||
|
const path = event.path || (event.composedPath && event.composedPath());
|
||||||
|
if (
|
||||||
|
event &&
|
||||||
|
!path.find(
|
||||||
|
(div) =>
|
||||||
|
div.classList &&
|
||||||
|
(div.classList.contains("tasks__head__tags") ||
|
||||||
|
div.classList.contains("tags__list"))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
setTags({ open: false, add: false, edit: false });
|
||||||
|
setTagInfo({ description: "", name: "" });
|
||||||
|
setColor("#aabbcc");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initListeners();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="tasks__head__tags">
|
||||||
|
<div
|
||||||
|
className="tags__add"
|
||||||
|
onClick={() => {
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
open: !tags.open
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>Список тегов</p>
|
||||||
|
<img className={tags.open ? "open" : ""} src={arrowDown} alt="arrow" />
|
||||||
|
</div>
|
||||||
|
{tags.open && (
|
||||||
|
<div className="tags__list">
|
||||||
|
{!tags.add && !tags.edit && (
|
||||||
|
<div
|
||||||
|
className="add-new-tag"
|
||||||
|
onClick={() =>
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
add: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<p>Добавить новый тег</p>
|
||||||
|
<span>+</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!tags.add && !tags.edit && (
|
||||||
|
<div className="tags__list__created">
|
||||||
|
{projectBoard.mark.map((tag) => {
|
||||||
|
return (
|
||||||
|
<div className="tag-item" key={tag.id}>
|
||||||
|
<div className="tag-item__info">
|
||||||
|
<span
|
||||||
|
className="tag-item__color"
|
||||||
|
style={{ background: tag.color }}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<span className="tag-item__info__name">{tag.slug}</span>
|
||||||
|
<p className="tag-item__description">{tag.title}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="tag-item__images">
|
||||||
|
<img
|
||||||
|
src={edit}
|
||||||
|
alt="edit"
|
||||||
|
onClick={() => {
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
edit: true
|
||||||
|
}));
|
||||||
|
setTagInfo({
|
||||||
|
description: tag.title,
|
||||||
|
name: tag.slug,
|
||||||
|
editMarkId: tag.id
|
||||||
|
});
|
||||||
|
setColor(tag.color);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
onClick={() => deleteTag(tag.id)}
|
||||||
|
className="delete"
|
||||||
|
src={close}
|
||||||
|
alt="delete"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{(tags.add || tags.edit) && (
|
||||||
|
<div className="form-tag">
|
||||||
|
<input
|
||||||
|
className="form-tag__input"
|
||||||
|
placeholder="Описание метки"
|
||||||
|
maxLength="25"
|
||||||
|
value={tagInfo.description}
|
||||||
|
onChange={(e) =>
|
||||||
|
setTagInfo((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
description: e.target.value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
className="form-tag__input"
|
||||||
|
placeholder="Тег"
|
||||||
|
value={tagInfo.name}
|
||||||
|
maxLength="10"
|
||||||
|
onChange={(e) =>
|
||||||
|
setTagInfo((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
name: e.target.value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<HexColorPicker color={color} onChange={setColor} />
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
tags.add ? addNewTag() : editTag();
|
||||||
|
}}
|
||||||
|
className={
|
||||||
|
tagInfo.name && tagInfo.description
|
||||||
|
? "form-tag__btn"
|
||||||
|
: "form-tag__btn disable"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{tags.add ? "Добавить" : "Изменить"}
|
||||||
|
</button>
|
||||||
|
{(tags.add || tags.edit) && (
|
||||||
|
<button
|
||||||
|
className={"form-tag__btn"}
|
||||||
|
onClick={() => {
|
||||||
|
setTags((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
add: false,
|
||||||
|
edit: false
|
||||||
|
}));
|
||||||
|
setTagInfo({
|
||||||
|
description: "",
|
||||||
|
name: ""
|
||||||
|
});
|
||||||
|
setColor("#aabbcc");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Отмена
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrackerTagList;
|
208
src/components/TrackerTagList/trackerTagList.scss
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
.tasks {
|
||||||
|
&__head {
|
||||||
|
&__tags {
|
||||||
|
position: relative;
|
||||||
|
img {
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.open {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.tags {
|
||||||
|
&__add {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 10px;
|
||||||
|
column-gap: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e3e2e2;
|
||||||
|
max-height: 30px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 16px;
|
||||||
|
border-radius: 50px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
background: #99b4f3;
|
||||||
|
color: white;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__list {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #d9d9d9;
|
||||||
|
z-index: 8;
|
||||||
|
top: 30px;
|
||||||
|
left: -35px;
|
||||||
|
width: 216px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__created {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
row-gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 0 8px 8px;
|
||||||
|
|
||||||
|
.tag-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
column-gap: 5px;
|
||||||
|
padding: 0px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
height: 40px;
|
||||||
|
max-height: 40px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
font-size: 12px;
|
||||||
|
word-break: break-word;
|
||||||
|
max-width: 115px;
|
||||||
|
max-height: 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-wrap: wrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__color {
|
||||||
|
width: 22.25px;
|
||||||
|
height: 23.217px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__images {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
row-gap: 3px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 10px;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-new-tag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
column-gap: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: white;
|
||||||
|
color: #252c32;
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 8px 8px 0px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 19px;
|
||||||
|
height: 19px;
|
||||||
|
border-radius: 50px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
background: #52b709;
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-tag {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 8px;
|
||||||
|
row-gap: 8px;
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 5px;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
outline: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #e3e2e2;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__btn {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
background: #252c32;
|
||||||
|
color: whitesmoke;
|
||||||
|
margin: 0 auto 0;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
padding: 5px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disable {
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,11 @@ import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
|
|||||||
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { urlForLocal } from "@utils/helper";
|
import { getCorrectDate } from "@utils/calendarHelper";
|
||||||
|
import { removeLast, urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { getCorrectDate } from "@components/Calendar/calendarHelper";
|
|
||||||
import TrackerTaskSubComment from "@components/TrackerTaskComment/TrackerTaskComment";
|
import TrackerTaskSubComment from "@components/TrackerTaskComment/TrackerTaskComment";
|
||||||
|
|
||||||
import del from "assets/icons/delete.svg";
|
import del from "assets/icons/delete.svg";
|
||||||
@ -93,7 +93,7 @@ export const TrackerTaskComment = ({
|
|||||||
}
|
}
|
||||||
alt="avatar"
|
alt="avatar"
|
||||||
/>
|
/>
|
||||||
<p>{comment.user.fio}</p>
|
<p>{removeLast(comment.user.fio)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="comments__list__item__date">
|
<div className="comments__list__item__date">
|
||||||
<span>{getCorrectDate(comment.created_at)}</span>
|
<span>{getCorrectDate(comment.created_at)}</span>
|
||||||
@ -127,11 +127,8 @@ export const TrackerTaskComment = ({
|
|||||||
"EasyImage",
|
"EasyImage",
|
||||||
"Image",
|
"Image",
|
||||||
"ImageCaption",
|
"ImageCaption",
|
||||||
"ImageStyle",
|
|
||||||
"ImageToolbar",
|
|
||||||
"ImageUpload",
|
"ImageUpload",
|
||||||
"MediaEmbed",
|
"MediaEmbed"
|
||||||
"BlockQuote"
|
|
||||||
]
|
]
|
||||||
}}
|
}}
|
||||||
onChange={(event, editor) => {
|
onChange={(event, editor) => {
|
||||||
|
@ -32,7 +32,7 @@ export const HeaderPageTestsQuiz = ({ isVisibilityButton }) => {
|
|||||||
</div>
|
</div>
|
||||||
{isVisibilityButton && (
|
{isVisibilityButton && (
|
||||||
<Link
|
<Link
|
||||||
to={"/Quiz/instruction"}
|
to={"/quiz/instruction"}
|
||||||
className="quiz-btn quiz-btn_restriction"
|
className="quiz-btn quiz-btn_restriction"
|
||||||
>
|
>
|
||||||
Пройти
|
Пройти
|
||||||
|
@ -5,6 +5,8 @@ import { selectUserInfo } from "@redux/quizSlice";
|
|||||||
|
|
||||||
import { urlForLocal } from "@utils/helper";
|
import { urlForLocal } from "@utils/helper";
|
||||||
|
|
||||||
|
import { Loader } from "@components/common/Loader/Loader";
|
||||||
|
|
||||||
// import { apiRequest } from "@api/request";
|
// import { apiRequest } from "@api/request";
|
||||||
import "./quiz.scss";
|
import "./quiz.scss";
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ export const HeaderQuiz = ({ header }) => {
|
|||||||
<div className="header-quiz">
|
<div className="header-quiz">
|
||||||
<div className="header-quiz__container">
|
<div className="header-quiz__container">
|
||||||
{!userInfo ? (
|
{!userInfo ? (
|
||||||
<h2>Loading...</h2>
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{header && (
|
{header && (
|
||||||
|
@ -6,6 +6,8 @@ import { selectedTest } from "@redux/quizSlice";
|
|||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { Loader } from "@components/common/Loader/Loader";
|
||||||
|
|
||||||
import comment from "assets/icons/comment.jpg";
|
import comment from "assets/icons/comment.jpg";
|
||||||
|
|
||||||
import "./quiz.scss";
|
import "./quiz.scss";
|
||||||
@ -24,7 +26,7 @@ export const Instruction = () => {
|
|||||||
<div className="instruction">
|
<div className="instruction">
|
||||||
<div className="instruction__container">
|
<div className="instruction__container">
|
||||||
{!countQuestions ? (
|
{!countQuestions ? (
|
||||||
<h2>Loading...</h2>
|
<Loader />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<h3 className="instruction__title quiz-title_h3">
|
<h3 className="instruction__title quiz-title_h3">
|
||||||
|
@ -44,7 +44,7 @@ export const MyTestsQuiz = ({ listTests }) => {
|
|||||||
</h3>
|
</h3>
|
||||||
<div className="item-test__body test-data">
|
<div className="item-test__body test-data">
|
||||||
<Link
|
<Link
|
||||||
to={"/Quiz/interjacent"}
|
to={"/quiz/interjacent"}
|
||||||
className="quiz-btn"
|
className="quiz-btn"
|
||||||
onClick={() => recordSelectedTest(item)}
|
onClick={() => recordSelectedTest(item)}
|
||||||
>
|
>
|
||||||
|