Просмотр исходного кода

UI when table view is disabled

feature/1522_UI_when_table_view_is_disabled-fe
Dzenis Hadzifejzovic 3 лет назад
Родитель
Сommit
b5544b6b51

+ 91
- 86
package-lock.json Просмотреть файл

"redux-saga": "^1.1.3", "redux-saga": "^1.1.3",
"sass": "^1.34.1", "sass": "^1.34.1",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"use-dynamic-refs": "^1.0.0",
"web-vitals": "^1.1.2", "web-vitals": "^1.1.2",
"yup": "^0.32.9" "yup": "^0.32.9"
}, },
"version": "8.19.0", "version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
"dev": true,
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.10.4", "@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"version": "7.14.0", "version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
"integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
"dev": true,
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": { "dependencies": {
"color-convert": "^2.0.1" "color-convert": "^2.0.1"
}, },
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.1.tgz", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.1.tgz",
"integrity": "sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==", "integrity": "sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==",
"dev": true,
"dependencies": { "dependencies": {
"deep-equal": "^2.0.5" "deep-equal": "^2.0.5"
} }
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"dependencies": { "dependencies": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
"supports-color": "^7.1.0" "supports-color": "^7.1.0"
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": { "dependencies": {
"color-name": "~1.1.4" "color-name": "~1.1.4"
}, },
"node_modules/@testing-library/dom/node_modules/color-name": { "node_modules/@testing-library/dom/node_modules/color-name": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"node_modules/@testing-library/dom/node_modules/deep-equal": { "node_modules/@testing-library/dom/node_modules/deep-equal": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz",
"integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==",
"dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.0", "call-bind": "^1.0.0",
"es-get-iterator": "^1.1.1", "es-get-iterator": "^1.1.1",
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
"node_modules/@testing-library/dom/node_modules/isarray": { "node_modules/@testing-library/dom/node_modules/isarray": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
}, },
"node_modules/@testing-library/dom/node_modules/pretty-format": { "node_modules/@testing-library/dom/node_modules/pretty-format": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true,
"dependencies": { "dependencies": {
"ansi-regex": "^5.0.1", "ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0", "ansi-styles": "^5.0.0",
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": { "dependencies": {
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
}, },
"node_modules/@types/aria-query": { "node_modules/@types/aria-query": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz",
"integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==",
"dev": true
"integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg=="
}, },
"node_modules/@types/babel__core": { "node_modules/@types/babel__core": {
"version": "7.1.14", "version": "7.1.14",
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
"dev": true,
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
}, },
"node_modules/dom-accessibility-api": { "node_modules/dom-accessibility-api": {
"version": "0.5.14", "version": "0.5.14",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",
"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==",
"dev": true
"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg=="
}, },
"node_modules/dom-converter": { "node_modules/dom-converter": {
"version": "0.2.0", "version": "0.2.0",
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz",
"integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==",
"dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"get-intrinsic": "^1.1.0", "get-intrinsic": "^1.1.0",
"node_modules/es-get-iterator/node_modules/isarray": { "node_modules/es-get-iterator/node_modules/isarray": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
}, },
"node_modules/es-to-primitive": { "node_modules/es-to-primitive": {
"version": "1.2.1", "version": "1.2.1",
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"dependencies": { "dependencies": {
"is-callable": "^1.1.3" "is-callable": "^1.1.3"
} }
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
"dev": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
"dev": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
"version": "1.1.9", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz",
"integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==",
"dev": true,
"dependencies": { "dependencies": {
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
"dev": true,
"funding": { "funding": {
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
"dev": true,
"dependencies": { "dependencies": {
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1" "get-intrinsic": "^1.1.1"
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="
}, },
"node_modules/jquery": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
"integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==",
"peer": true
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
"integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=",
"dev": true,
"bin": { "bin": {
"lz-string": "bin/bin.js" "lz-string": "bin/bin.js"
} }
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz",
"integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==", "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==",
"dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"node_modules/typescript": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
"integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/typescript-compare": { "node_modules/typescript-compare": {
"version": "0.0.2", "version": "0.0.2",
"resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz",
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/use-dynamic-refs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/use-dynamic-refs/-/use-dynamic-refs-1.0.0.tgz",
"integrity": "sha512-1Ky+Jaj6MIpTRz6NTaCLVm/iDXfRNwUMH9X7BkLtgSL2RCXHQhK2p9SVhut8jZPDfxLDtOIYNM3txsiLXd4yVQ==",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^16.0.0"
}
},
"node_modules/util": { "node_modules/util": {
"version": "0.11.1", "version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
"dev": true,
"dependencies": { "dependencies": {
"is-map": "^2.0.1", "is-map": "^2.0.1",
"is-set": "^2.0.1", "is-set": "^2.0.1",
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz",
"integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==",
"dev": true,
"dependencies": { "dependencies": {
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"@emotion/use-insertion-effect-with-fallbacks": { "@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.0.0", "version": "1.0.0",
"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.0.tgz",
"integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A=="
"integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==",
"requires": {}
}, },
"@emotion/utils": { "@emotion/utils": {
"version": "1.2.0", "version": "1.2.0",
"@mui/types": { "@mui/types": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz",
"integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA=="
"integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==",
"requires": {}
}, },
"@mui/utils": { "@mui/utils": {
"version": "5.10.9", "version": "5.10.9",
"version": "8.19.0", "version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
"dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.10.4", "@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.12.5",
"version": "7.14.0", "version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
"integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
"dev": true,
"requires": { "requires": {
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": { "requires": {
"color-convert": "^2.0.1" "color-convert": "^2.0.1"
} }
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.1.tgz", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.1.tgz",
"integrity": "sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==", "integrity": "sha512-4cPQjOYM2mqq7mZG8CSxkUvL2Yv/x29VhGq5LKehTsxRnoVQps1YGt9NyjcNQsznEsD4rr8a6zGxqeNTqJWjpA==",
"dev": true,
"requires": { "requires": {
"deep-equal": "^2.0.5" "deep-equal": "^2.0.5"
} }
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"requires": { "requires": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
"supports-color": "^7.1.0" "supports-color": "^7.1.0"
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": { "requires": {
"color-name": "~1.1.4" "color-name": "~1.1.4"
} }
"color-name": { "color-name": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"deep-equal": { "deep-equal": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.5.tgz",
"integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==", "integrity": "sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==",
"dev": true,
"requires": { "requires": {
"call-bind": "^1.0.0", "call-bind": "^1.0.0",
"es-get-iterator": "^1.1.1", "es-get-iterator": "^1.1.1",
"has-flag": { "has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
}, },
"isarray": { "isarray": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
}, },
"pretty-format": { "pretty-format": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true,
"requires": { "requires": {
"ansi-regex": "^5.0.1", "ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0", "ansi-styles": "^5.0.0",
"ansi-styles": { "ansi-styles": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="
} }
} }
}, },
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": { "requires": {
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
} }
"@types/aria-query": { "@types/aria-query": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz",
"integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==",
"dev": true
"integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg=="
}, },
"@types/babel__core": { "@types/babel__core": {
"version": "7.1.14", "version": "7.1.14",
"acorn-jsx": { "acorn-jsx": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"requires": {}
}, },
"acorn-walk": { "acorn-walk": {
"version": "7.2.0", "version": "7.2.0",
"ajv-errors": { "ajv-errors": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ=="
"integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
"requires": {}
}, },
"ajv-keywords": { "ajv-keywords": {
"version": "3.5.2", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"requires": {}
}, },
"alphanum-sort": { "alphanum-sort": {
"version": "1.0.2", "version": "1.0.2",
"available-typed-arrays": { "available-typed-arrays": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
"dev": true
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
}, },
"axe-core": { "axe-core": {
"version": "4.2.2", "version": "4.2.2",
"babel-plugin-named-asset-import": { "babel-plugin-named-asset-import": {
"version": "0.3.7", "version": "0.3.7",
"resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz",
"integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw=="
"integrity": "sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw==",
"requires": {}
}, },
"babel-plugin-polyfill-corejs2": { "babel-plugin-polyfill-corejs2": {
"version": "0.2.2", "version": "0.2.2",
"dom-accessibility-api": { "dom-accessibility-api": {
"version": "0.5.14", "version": "0.5.14",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz",
"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==",
"dev": true
"integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg=="
}, },
"dom-converter": { "dom-converter": {
"version": "0.2.0", "version": "0.2.0",
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz",
"integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==",
"dev": true,
"requires": { "requires": {
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"get-intrinsic": "^1.1.0", "get-intrinsic": "^1.1.0",
"isarray": { "isarray": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
} }
} }
}, },
"version": "8.3.0", "version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
"integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
"dev": true
"dev": true,
"requires": {}
}, },
"eslint-config-react-app": { "eslint-config-react-app": {
"version": "6.0.0", "version": "6.0.0",
"eslint-plugin-react-hooks": { "eslint-plugin-react-hooks": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ=="
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
"requires": {}
}, },
"eslint-plugin-security": { "eslint-plugin-security": {
"version": "1.4.0", "version": "1.4.0",
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"requires": { "requires": {
"is-callable": "^1.1.3" "is-callable": "^1.1.3"
} }
"is-map": { "is-map": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
"dev": true
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg=="
}, },
"is-module": { "is-module": {
"version": "1.0.0", "version": "1.0.0",
"is-set": { "is-set": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
"dev": true
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g=="
}, },
"is-shared-array-buffer": { "is-shared-array-buffer": {
"version": "1.0.2", "version": "1.0.2",
"version": "1.1.9", "version": "1.1.9",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz",
"integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==",
"dev": true,
"requires": { "requires": {
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"is-weakmap": { "is-weakmap": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
"dev": true
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA=="
}, },
"is-weakref": { "is-weakref": {
"version": "1.0.2", "version": "1.0.2",
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
"dev": true,
"requires": { "requires": {
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1" "get-intrinsic": "^1.1.1"
"jest-pnp-resolver": { "jest-pnp-resolver": {
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w=="
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
"requires": {}
}, },
"jest-regex-util": { "jest-regex-util": {
"version": "26.0.0", "version": "26.0.0",
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==" "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="
}, },
"jquery": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
"integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw==",
"peer": true
},
"js-tokens": { "js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"lz-string": { "lz-string": {
"version": "1.4.4", "version": "1.4.4",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
"integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=",
"dev": true
"integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY="
}, },
"magic-string": { "magic-string": {
"version": "0.25.7", "version": "0.25.7",
"prettier": { "prettier": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz",
"integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==",
"dev": true
"integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA=="
}, },
"prettier-linter-helpers": { "prettier-linter-helpers": {
"version": "1.0.0", "version": "1.0.0",
"redux-thunk": { "redux-thunk": {
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q=="
"integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
"requires": {}
}, },
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"slick-carousel": { "slick-carousel": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz",
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA=="
"integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==",
"requires": {}
}, },
"snapdragon": { "snapdragon": {
"version": "0.8.2", "version": "0.8.2",
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"typescript": {
"version": "4.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
"integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==",
"peer": true
},
"typescript-compare": { "typescript-compare": {
"version": "0.0.2", "version": "0.0.2",
"resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz", "resolved": "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz",
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
}, },
"use-dynamic-refs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/use-dynamic-refs/-/use-dynamic-refs-1.0.0.tgz",
"integrity": "sha512-1Ky+Jaj6MIpTRz6NTaCLVm/iDXfRNwUMH9X7BkLtgSL2RCXHQhK2p9SVhut8jZPDfxLDtOIYNM3txsiLXd4yVQ==",
"requires": {}
},
"util": { "util": {
"version": "0.11.1", "version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
"dev": true,
"requires": { "requires": {
"is-map": "^2.0.1", "is-map": "^2.0.1",
"is-set": "^2.0.1", "is-set": "^2.0.1",
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz",
"integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==",
"dev": true,
"requires": { "requires": {
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"ws": { "ws": {
"version": "7.4.6", "version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"requires": {}
}, },
"xdg-basedir": { "xdg-basedir": {
"version": "4.0.0", "version": "4.0.0",

+ 1
- 0
package.json Просмотреть файл

"redux-saga": "^1.1.3", "redux-saga": "^1.1.3",
"sass": "^1.34.1", "sass": "^1.34.1",
"slick-carousel": "^1.8.1", "slick-carousel": "^1.8.1",
"use-dynamic-refs": "^1.0.0",
"web-vitals": "^1.1.2", "web-vitals": "^1.1.2",
"yup": "^0.32.9" "yup": "^0.32.9"
}, },

Двоичные данные
src/assets/images/calendar.png Просмотреть файл


+ 61
- 0
src/assets/styles/components/_candidate-card.scss Просмотреть файл

.candidate-card-container {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 36px;
gap: 18px;
isolation: isolate;
background: #ffffff;
border: 1px solid #e4e4e4;
border-radius: 18px;
width: 354px;
height: 238px;
}

.candidate-card-container:active {
animation-timing-function: ease-in-out;
animation-duration: 300ms;

}

.candidate-card-container:hover{
cursor: pointer;
}

.candidate-card-tecnologies-container {
display: flex;
}

.candidate-card-date {
font-family: Source Sans Pro;
font-size: 12px;
font-weight: 400;
line-height: 15px;
letter-spacing: 0em;
}

.candidate-card-applicant-name {
font-family: Source Sans Pro;
font-size: 16px;
font-weight: 600;
line-height: 20px;
letter-spacing: 0em;
color: #226cb0;
}

.candidate-card-years {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 20px;
color: #272727;
}

.candidate-card-techologies {
display: flex;
justify-content: space-between;
gap: 18px;
}

+ 489
- 0
src/assets/styles/components/_candidatePage copy.scss Просмотреть файл

.main-candidate-container {
display: flex;
flex-direction: column;
}

.top-candidate-container {
display: flex;
width: 100%;
justify-content: space-between;
}

.candidate-header {
height: 36px;
font-family: Source Sans Pro;
font-size: 36px;
font-weight: 600;
line-height: 36px;
letter-spacing: 0.02em;
text-align: left;
color: #272727;
}

.separation-line {
margin-left: 5px;
margin-right: 5px;
font-size: 20px;
align-self: flex-end;
}

.candidate-lower-header {
font-family: Source Sans Pro;
font-size: 24px;
font-weight: 600;
line-height: 32px;
letter-spacing: 0.02em;
text-align: left;
color: #226cb0;
align-self: flex-end;
}
.candidate-option-container {
display: flex;
height: 38px;
}

.content-candidate-container {
display: flex;
justify-content: space-between;
margin-top: 14px;
}

.technologies-candidate-container {
display: flex;
margin-top: 18px;
}

.technology-candidate-card {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 9px;
gap: 10px;
background: #ffffff;
border: 1px solid #e4e4e4;
border-radius: 9px;
}

.technology-candidate-card:not(:last-child) {
margin-right: 18px;
}

.comment-container {
width: 612px;
height: 404px;
background: #ffffff;
border: 1px solid #e4e4e4;
border-radius: 12px;
margin-top: 16px;
}

.candidate-informations-container {
display: flex;
flex-direction: column;
}

.candidate-informations-sub-container {
margin-top: 36px;
}

.informations-candidate-header {
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 20px;
color: #272727;
}

.candidate-property-container {
display: flex;
flex-direction: column;
}

.candidate-property {
margin-top: 18px;
font-family: Source Sans Pro;
font-size: 16px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0em;
}

.candidate-property-value {
@extend .candidate-property;
color: #1e92d0;
}

.candidate-informations-sub-container {
display: flex;
}

.comment-container {
display: flex;
flex-direction: column;
padding-left: 36px;
padding-right: 36px;
padding-top: 36px;
}

.comment-sub-container {
display: flex;
align-items: center;
}

.comment-sub-container:not(:first-child) {
margin-top: 36px;
}

.comment-sender {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
box-sizing: border-box;
border: 1px solid;
border-color: #226cb0;
}

.comment-sender p {
color: #226cb0;
}

.comment-message {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
padding: 9px;
gap: 9px;
height: 62px;
background: #f4f4f4;
border-radius: 12px;
margin-left: 18px;
}

.comment-message-content {
align-self: flex-start;
height: 20px;
font-family: "Source Sans Pro";
font-style: normal;
font-size: 16px;
line-height: 20px;
}

.comment-message-date {
align-self: flex-end;
height: 15px;
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 400;
font-size: 12px;
line-height: 15px;
color: #272727;
}

.comment-separation-line {
width: 100%;
height: 0px;
border: 1px solid #e4e4e4;
background: #e4e4e4;
}

.send-comment-container {
margin-top: 18px;
}

.send-comment-container p {
font-family: "Source Sans Pro";
font-weight: 400;
font-size: 16px;
line-height: 20px;
color: #9d9d9d;
}

.send-comment-sub-container {
display: flex;
margin-top: 9px;
height: 56px;
margin-bottom: 36px;
}

.comment-send-btn {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 18px 36px;
gap: 10px;
background: #ffffff;
border: 1px solid #226cb0;
border-radius: 9px;
border: 1px solid #226cb0;
width: 156px;
margin-left: 18px;
}

.comment-send-btn:hover {
cursor: pointer;
}

.comment-send-btn p {
width: 62px;
height: 15px;
font-family: "Source Sans Pro";
font-style: normal;
font-weight: 600;
font-size: 12px;
line-height: 15px;
letter-spacing: 0.04em;
text-transform: uppercase;
color: #226cb0;
flex: none;
order: 1;
flex-grow: 0;
}

.comment-send-btn img {
width: 12px;
height: 12px;
}

.candidate-users {
background-color: #f4f4f4;
}

.candidate-user {
color: #226cb0;
}

.applicant-ads-container {
margin-top: 36px;
}

.applicant-ads-container > p {
font-family: "Source Sans Pro";
font-weight: 600;
font-size: 24px;
line-height: 32px;
letter-spacing: 0.02em;
color: #272727;
}

.applicant-ads-sub-container {
margin-top: 18px;
display: flex;
margin-left: -20px;
}

.applicant-add {
display: flex;
flex-direction: column;
align-items: center;
padding: 36px;
gap: 18px;
background: #ffffff;
border: 1px solid #e4e4e4;
border-radius: 12px;
width: 247px;
height: 238px;
cursor: pointer;
}

.applicant-add-date {
font-family: Source Sans Pro;
font-size: 12px;
font-weight: 400;
line-height: 15px;
letter-spacing: 0em;
}

.applicant-add-title {
font-family: "Source Sans Pro";
font-weight: 600;
font-size: 16px;
line-height: 20px;
color: #226cb0;
}

.applicant-add-site {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: #ffffff;
padding: 6px;
border: 1px solid #e4e4e4;
border-radius: 8px;
font-size: 16px;
font-family: "Source Sans Pro";
font-weight: 400;
color: #272727;
}

.applicant-ads-buttons-container {
display: flex;
align-self: flex-end;
align-items: center;
margin-bottom: 54px;
margin-top: 18px;
}

.applicant-cv-button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 18px 72px;
gap: 10px;
background: #226cb0;
border-radius: 9px;
width: 212px;
height: 51px;
font-family: "Source Sans Pro";
font-weight: 600;
font-size: 12px;
line-height: 15px;
letter-spacing: 0.04em;
text-transform: uppercase;
color: #ffffff;
}

.applicant-ads-back-button {
margin-right: 36px;
font-family: "Source Sans Pro";
font-weight: 400;
font-size: 16px;
line-height: 20px;
text-decoration-line: underline;
color: #226cb0;
}

.tagStyle {
color: #226cb0;
font-family: Source Sans Pro;
font-size: 16px;
font-weight: 600;
line-height: 20px;
letter-spacing: 0em;
}

.comment-input {
@extend .tagStyle;
width: 368px;
}


.comment-input ::placeholder {
width: 139px;
height: 20px;
font-family: "Source Sans Pro";
font-style: italic;
font-weight: 400;
font-size: 16px;
line-height: 20px;
color: #9d9d9d;
flex: none;
order: 0;
flex-grow: 0;
}

.comment-input-list{
@extend .tagStyle;
}

@media only screen and (max-width: 930px) {
.comment-container {
width:500px;
}
}

@media only screen and (max-width: 820px) {
.comment-container {
width:400px;
};
.comment-send-btn{
width: 130;
padding: 12px 28px;
};
.send-comment-sub-container{
height: 45px;
margin-bottom: 20px
};
.comment-input ::placeholder{
font-size: 14px;
line-height: 18px;
padding-top:2px;
}
}

@media only screen and (max-width: 700px) {
.comment-container {
width:380px;
}
.comment-send-btn{
width: 110;
padding: 10px 20px;
};
}

@media only screen and (max-width:680px) {
.content-candidate-container{
flex-direction: column;
}
.comment-container {
margin-top: 30px;
}
}

@media only screen and (max-width:540px) {
.candidate-header{
height: 30px;
font-family: Source Sans Pro;
font-size: 30px;
line-height: 30px;
}

.candidate-lower-header{
font-size: 18px;
line-height: 26px;
}

.applicant-cv-button {
padding: 10px 52px;
gap: 7px;
border-radius: 7px;
width: 180px;
height: 40px;
font-size: 10px;
line-height: 12px;
text-align: center;
}
}

@media only screen and (max-width:480px) {
.comment-container {
width:297px;
}
.comment-send-btn{
padding: 5px 5px;
};
.comment-container{
padding: 20px;
}

.candidate-header{
height: 20x;
font-size: 20px;
line-height: 20px;
}

.candidate-lower-header{
font-size: 17px;
line-height:17px;
}
}

+ 87
- 13
src/assets/styles/components/_candidatesPage.scss Просмотреть файл

.main-candidates-container { .main-candidates-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-bottom: 36px;
} }


.top-candidates-container { .top-candidates-container {
text-transform: none; text-transform: none;
} }


.candidate-btn-mobile{
@extend .candidate-btn;
// overrride style from candidate-btn class
margin-left: 10px;
.all-white-btn {
background: linear-gradient(0deg, #e8f7ff, #e8f7ff),
linear-gradient(0deg, #226cb0, #226cb0);
}

.candidate-btn-mobile {
@extend .candidate-btn;
// overrride style from candidate-btn class
margin-left: 10px;
} }


.invite-btn { .invite-btn {
display: flex; display: flex;
align-self: flex-end; align-self: flex-end;
margin-left: 60px; margin-left: 60px;
margin-bottom: 36px;
} }


.candidates-options-container { .candidates-options-container {


.candidates-table { .candidates-table {
margin-top: 30px; margin-top: 30px;
width: 100%;
display: flex; display: flex;
flex-direction: column;
min-height: 70vh; min-height: 70vh;
align-items: space-between; align-items: space-between;
@include media-below($bp-xl) { @include media-below($bp-xl) {
margin-left: 10px; margin-left: 10px;
} }


.candidate-image-mobile{
position: "relative";
top: -0.25
.candidate-image-mobile {
position: "relative";
top: -0.25;
} }


.invite-btn-color { .invite-btn-color {
background-color: #226cb0; background-color: #226cb0;
} }



@media only screen and (max-width: 376px) { @media only screen and (max-width: 376px) {
.main-candidates-container{
margin-left: 50px;
margin-right: 50px;
}
}
.main-candidates-container {
margin-left: 50px;
margin-right: 50px;
}
}

.ads-candidates-container {
max-height: 837px;
overflow-y: auto;
overflow-x: hidden;
}

.ads-candidates-slider {
display: flex;
}

.ads-candidates-top-container {
display: flex;
align-items: center;
}

.ads-candidates-title {
font-family: Source Sans Pro;
font-size: 24px;
font-weight: 600;
letter-spacing: 0.02em;
margin-left: 18px;
}

.ads-candidates-numberOfApplicants {
font-family: Source Sans Pro;
font-size: 16px;
font-weight: 600;
letter-spacing: 0em;
color: #226cb0;
margin-left: 5px;
}

.proba {
margin-top: 39px;
}

.proba > div:not(:first-child) {
margin-top: 79px;
}

.proba2 {
margin-left: 27px;
}

.filter-date-container {
display: flex;
flex-direction: column;
margin-top: 10px;
}

.filter-date-container input {
border: 1px solid gray;
border-radius: 4px;
height: 40px;
padding-left: 12px;
font-family: Source Sans Pro;
font-size: 16px;
font-style: italic;
font-weight: 400;
line-height: 20px;
letter-spacing: 0em;
text-align: left;
color: #9d9d9d;
margin-top: 5px;
}

+ 33
- 0
src/components/Candidates/CandidateAd.js Просмотреть файл

import React from "react";
import PropTypes from "prop-types";
import { formatDate } from "../../util/helpers/dateHelpers";
import dotnetImage from "../../assets/images/.net_icon.png";

const CandidateAd = ({ add, className, onclick }) => {
return add === undefined ? (
<p></p>
) : (
<div
onClick={onclick}
style={{ cursor: "pointer" }}
className={`applicant-add ${className !== undefined ? className : ""}`}
>
<p className="applicant-add-date">{formatDate(add.createdAt)}</p>
<p className="applicant-add-title">{add.title}</p>
<img
src={dotnetImage}
alt="technology-image"
className="applicant-add-technology-image"
/>
<div className="applicant-add-site">dilig.net</div>
</div>
);
};

CandidateAd.propTypes = {
add: PropTypes.object,
className: PropTypes.any,
onclick: PropTypes.func,
};

export default CandidateAd;

+ 62
- 0
src/components/Candidates/CandidateCard.js Просмотреть файл

import React from "react";
import PropTypes from "prop-types";
import { formatDate } from "../../util/helpers/dateHelpers";
import { CANDIDATES_PAGE } from "../../constants/pages";

const CandidateCard = ({ candidate, className,history }) => {

const navigateToDetailsPage = () => {
history.push({
pathname: CANDIDATES_PAGE + "/" + candidate.applicantId,
state: {
from: history.location.pathname,
},
});
}

return candidate == null ? (
<p></p>
) : (
<div
onClick={navigateToDetailsPage}
className={`candidate-card-container ${
className !== undefined ? className : ""
}`}
>
<p className="candidate-card-date">
{formatDate(candidate.dateOfApplication)}
</p>
<p className="candidate-card-applicant-name">
{candidate.firstName} {candidate.lastName}
</p>
<p className="candidate-card-years">
{candidate.experience === 0
? "No experience"
: candidate.experience + "+ years of experience"}
</p>
<div className="candidate-card-tecnologies-container">
{candidate.technologyApplicants.map((technology, index) => (
<p key={index}>{technology.name}</p>
))}
</div>
<div className="candidate-card-techologies">
{candidate.technologyApplicants.map((technology, index) => (
<div key={index} className="applicant-add-site">
{technology.technology.name}
</div>
))}
</div>
<a className="cvLink">
CV {candidate.firstName} {candidate.lastName}.pdf
</a>
</div>
);
};

CandidateCard.propTypes = {
candidate: PropTypes.object,
className: PropTypes.any,
history:PropTypes.any
};

export default CandidateCard;

+ 237
- 0
src/components/Candidates/CandidateFilters.js Просмотреть файл

import React, { useState } from "react";
import PropType from "prop-types";
import Box from "@mui/material/Box";
import Drawer from "@mui/material/Drawer";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import Slider from "@mui/material/Slider";
import filterIcon from "../../assets/images/filter_vector.png";
import x from "../../assets/images/x.png";
import { filterCandidates } from "../../store/actions/candidates/candidatesActions";
import { useDispatch } from "react-redux";
import { formatDateInput } from "../../util/helpers/dateHelpers";

const CandidateFilters = ({ open, handleClose,pageSize,currentPage }) => {
const dispatch = useDispatch();
const [sliderValue, setSliderValue] = useState([0, 0]);
const [startingDate,setStartingDate] = useState('')
const [endingDate,setEndingDate] = useState('')
const [technologies, setTechnologies] = useState([
{ name: "react", isChecked: false },
{ name: "angular", isChecked: false },
{ name: "sql", isChecked: false },
{ name: "nodejs", isChecked: false },
{ name: ".net", isChecked: false },
{ name: "git", isChecked: false },
{ name: "html/css", isChecked: false },
{ name: "vanillaJS", isChecked: false },
]);
const [typesOfEmployments, setTypesOfEmployments] = useState([
{ name: "Posao", isChecked: true },
{ name: "Intership", isChecked: false },
]);

const handleSliderChange = (_, newValue) => {
setSliderValue(newValue);
};

const updateState = (name, value) => {
const newState = technologies.map((obj) => {
if (obj.name === name) {
return { ...obj, isChecked: value };
}
return obj;
});
setTechnologies(newState);
};

const updateTypeState = (name, value) => {
const newState = typesOfEmployments.map((obj) => {
if (obj.name === name) {
return { ...obj, isChecked: value };
} else {
return { ...obj, isChecked: false };
}
});
setTypesOfEmployments(newState);
};

const handleTechologiesChange = (event) => {
updateState(event.target.name, event.target.checked);
};

const getSelectedEmploymentType = () => {
return typesOfEmployments.filter((e) => e.isChecked === true);
};

const getSelectedTechnologies = () => {
let k = technologies.filter(t => t.isChecked === true)
let n = []
k.forEach(technology => {
n.push(technology.name)
});

return n;
}

const handleChangeTypeOfEmployment = (name) => {
updateTypeState(name, true);
};

const handleApiResponseSuccess = () => {
handleClose()
}

const fiterItems = () => {
dispatch(
filterCandidates({
pageSize,
currentPage,
minExperience: sliderValue[0],
maxExperience: sliderValue[1],
employmentType: getSelectedEmploymentType()[0].name,
minDateOfApplication:startingDate,
maxDateOfApplication:endingDate,
technologies:getSelectedTechnologies(),
handleApiResponseSuccess
})
);
};

const handleChangeStartingDate = (event) => {
console.log(event)
setStartingDate(event.target.value)
}

const handleChangeEndingDate = (event) => {
console.log(event)
setEndingDate(event.target.value)
}

const getDayBeforeToday = (date = new Date()) => {
const previous = new Date(date.getTime());
previous.setDate(date.getDate() - 1);
return previous;
}

const list = () => (
<Box
sx={{
width: 360,
height: "100%",
borderRadius: "18px 0 0 18px",
padding: "36px",
}}
role="presentation"
onKeyDown={handleClose}
>
<div>
<div className="ad-filters-header-container">
<div className="ad-filters-header">
<img src={filterIcon} alt="filter_icon" />
<h3>Filteri</h3>
<p>
<sub>| Kandidati</sub>
</p>
</div>
<div className="ad-filters-header-close" onClick={handleClose}>
<img src={x} alt="x" />
</div>
</div>
<div className="ad-filters-experience">
<div className="ad-filters-sub-title">
<p>Godine iskustva</p>
</div>
<div className="ad-filters-experience-slider">
<Slider
getAriaLabel={() => "Temperature range"}
value={sliderValue}
onChange={handleSliderChange}
valueLabelDisplay="auto"
max={20}
/>
</div>
</div>
<div className="ad-filters-technologies">
<div className="ad-filters-sub-title">
<p>Tehnologije</p>
</div>
<div className="ad-filters-technologies-checkboxes">
<FormGroup>
{technologies.map((technology, index) => (
<FormControlLabel
key={index}
control={
<Checkbox
checked={technology.isChecked}
name={technology.name}
onChange={handleTechologiesChange}
/>
}
label={technology.name}
/>
))}
</FormGroup>
</div>
</div>
<div className="ad-filters-technologies">
<div className="ad-filters-sub-title">
<p>Tip zaposlenja</p>
</div>
<div className="ad-filters-employment-type">
{typesOfEmployments.map((type, index) => (
<button
key={index}
className={
type.isChecked === false
? "c-btn c-btn--primary-outlined"
: "c-btn c-btn--primary"
}
onClick={() => handleChangeTypeOfEmployment(type.name)}
>
{type.name}
</button>
))}
</div>
</div>
<div className="ad-filters-technologies" style={{ marginTop: "35px" }}>
<div className="ad-filters-sub-title">
<p>Datum prijave</p>
<div className="filter-date-container">
<p>Od</p>
<input type="date" id="start" max={formatDateInput(getDayBeforeToday())} value={startingDate} onChange={handleChangeStartingDate}/>
</div>
<div className="filter-date-container">
<p>Do</p>
<input type="date" id="start" max={ formatDateInput(new Date())} value={endingDate} onChange={handleChangeEndingDate}/>
</div>
</div>
</div>
<div className="ad-filters-search" style={{ marginTop: "45px" }}>
<button className="c-btn c-btn--primary" onClick={fiterItems}>
Pretrazi
</button>
</div>
</div>
</Box>
);

return (
<div>
<Drawer anchor="right" open={open} onClose={handleClose}>
{list()}
</Drawer>
</div>
);
};

CandidateFilters.propTypes = {
open: PropType.any,
handleClose: PropType.func,
candidates: PropType.array,
currentPage:PropType.number,
pageSize:PropType.number
};

export default CandidateFilters;

+ 2
- 0
src/constants/keyCodeConstants.js Просмотреть файл

export const LEFT_ARROW_KEYCODE = 37; export const LEFT_ARROW_KEYCODE = 37;
export const BACKSPACE_KEYCODE = 8; export const BACKSPACE_KEYCODE = 8;
export const TAB_KEYCODE = 9; export const TAB_KEYCODE = 9;

export const PAGE_SIZE_CANDIDATES = 6;

+ 1
- 0
src/main.scss Просмотреть файл

@import './assets/styles/components/usersPage'; @import './assets/styles/components/usersPage';
@import './assets/styles/components/candidatesPage'; @import './assets/styles/components/candidatesPage';
@import './assets/styles/components/candidatePage'; @import './assets/styles/components/candidatePage';
@import './assets/styles/components/candidate-card';
@import './assets/styles/components/loader'; @import './assets/styles/components/loader';
@import './assets/styles/components/radio'; @import './assets/styles/components/radio';
@import './assets/styles/components/modal'; @import './assets/styles/components/modal';

+ 124
- 26
src/pages/CandidateDetailsPage/CandidateDetailsPage.js Просмотреть файл

import React from "react"; import React from "react";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef } from "react";
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import editImage from "../../../src/assets/images/edit.png";
import deleteImage from "../../../src/assets/images/delete.png"; import deleteImage from "../../../src/assets/images/delete.png";
import planeImage from "../../../src/assets/images/planeVectorBlue.png"; import planeImage from "../../../src/assets/images/planeVectorBlue.png";
import dotnetImage from "../../../src/assets/images/.net_icon.png";
import IconButton from "../../components/IconButton/IconButton"; import IconButton from "../../components/IconButton/IconButton";
import { formatDateTime, formatDate } from "../../util/helpers/dateHelpers";
import { formatDateTime } from "../../util/helpers/dateHelpers";
import { setUsersReq } from "../../store/actions/users/usersActions"; import { setUsersReq } from "../../store/actions/users/usersActions";
import { createCandidateComment } from "../../store/actions/candidate/candidateActions"; import { createCandidateComment } from "../../store/actions/candidate/candidateActions";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { fetchCandidate } from "../../store/actions/candidate/candidateActions"; import { fetchCandidate } from "../../store/actions/candidate/candidateActions";
import { useMediaQuery } from "@mui/material"; import { useMediaQuery } from "@mui/material";
import { useTheme } from "@mui/system"; import { useTheme } from "@mui/system";
import CandidateAd from '../../components/Candidates/CandidateAd';
import Slider from "react-slick";
import arrow_left from "../../assets/images/arrow_left.png";
import arrow_right from "../../assets/images/arrow_right.png";
import { ADS_PAGE } from "../../constants/pages";
import PropTypes from "prop-types";
import { deleteCandidate } from "../../request/candidatesRequest";


const CandidateDetailsPage = () => {
const CandidateDetailsPage = ({history}) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { users } = useSelector((s) => s.users); const { users } = useSelector((s) => s.users);
const { user } = useSelector((s) => s.user); const { user } = useSelector((s) => s.user);
const messageContainer = useRef(); const messageContainer = useRef();
const theme = useTheme(); const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down("680")); const matches = useMediaQuery(theme.breakpoints.down("680"));
const adsSliderRef = useRef();


useEffect(() => { useEffect(() => {
dispatch(fetchCandidate({ id })); dispatch(fetchCandidate({ id }));
}; };


const getArray = () => { const getArray = () => {
let newArray = users?.map(function (value) {
let newArray = users.map(function (value) {
return { id: value.id, display: value.firstName + value.lastName }; return { id: value.id, display: value.firstName + value.lastName };
}); });


}; };


const tranformDisplay = (id, display) => { const tranformDisplay = (id, display) => {
console.log(id);
return "@" + display + " "; return "@" + display + " ";
}; };


}, },
}) })
); );

// var regex = /\[(.*?)\]/;
// var matched = regex.exec(value);
// user = matched[1];
// let email = "dzenis1945@outlook.com";
// let poruka = "dsadas";
setValue(""); setValue("");
}; };


var settings = {
dots: false,
infinite: false,
speed: 400,
slidesToShow: 5,
slidesToScroll: 5,
initialSlide: 0,
arrows: true,
variableWidth: true,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 4,
slidesToScroll: 4,
infinite: true,
dots: false,
},
},
{
breakpoint: 900,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
initialSlide: 0,
},
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
},
},
],
};

const getDummyAds = (len) => {
const ads = [];

for (let i = 0; i < 5 - len + 1; i++) {
ads.push(<CandidateAd key={i} className="hiddenAd" />);
}

return ads;
};

const activeAdsArrowLeftHandler = () => {
adsSliderRef.current.slickPrev();
};

const activeAdsArrowRightHandler = () => {
adsSliderRef.current.slickNext();
};

const deleteCurrentCandidate = () => {
dispatch(deleteCandidate({id}))
}

const navigateToDetailsPage = (id) => {
history.push({
pathname: ADS_PAGE + "/" + id,
state: {
from: history.location.pathname,
},
});
}

return (candidate && Object.keys(candidate).length === 0) || return (candidate && Object.keys(candidate).length === 0) ||
user === undefined ? ( user === undefined ? (
<p>Loading...</p> <p>Loading...</p>
</p> </p>
</div> </div>
<div className="candidate-option-container"> <div className="candidate-option-container">
<IconButton className="c-btn c-btn--primary-outlined candidate-btn">
<IconButton className="c-btn c-btn--primary-outlined candidate-btn" onClick={deleteCurrentCandidate}>
Obrisi Obrisi
<img src={deleteImage} alt="delete" className="candidates-image" /> <img src={deleteImage} alt="delete" className="candidates-image" />
</IconButton> </IconButton>
<IconButton className="c-btn c-btn--primary-outlined candidate-btn">
Uredi profil
<img src={editImage} alt="edit" className="candidates-image" />
</IconButton>
</div> </div>
</div> </div>
<div className="content-candidate-container"> <div className="content-candidate-container">
: "Experience:" + candidate.experience} : "Experience:" + candidate.experience}
</p> </p>
<div className="technologies-candidate-container"> <div className="technologies-candidate-container">
{candidate?.technologyApplicants?.map((obj, index) => (
{candidate.technologyApplicants.map((obj, index) => (
<div className="technology-candidate-card" key={index}> <div className="technology-candidate-card" key={index}>
{obj.technology.name} {obj.technology.name}
</div> </div>
}} }}
ref={messageContainer} ref={messageContainer}
> >
{candidate?.comments?.map((comment, index) => (
{candidate.comments.map((comment, index) => (
<div className="comment-sub-container" key={index}> <div className="comment-sub-container" key={index}>
<div className="comment-sender"> <div className="comment-sender">
<p> <p>
</div> </div>
<div className="applicant-ads-container"> <div className="applicant-ads-container">
<p>Sve prijave</p> <p>Sve prijave</p>
<div className="applicant-ads-sub-container">
{candidate?.ads?.map((add, index) => (
<div key={index} className="applicant-add">
<p className="applicant-add-date">
{formatDate(add.createdAt)}
</p>
<p className="applicant-add-title">{add.title}</p>
<img
src={dotnetImage}
alt="technology-image"
className="applicant-add-technology-image"
<div
style={{ display: "flex", alignItems: "center", marginTop: "18px" }}
>
<div>
{candidate.ads.length > 5 && (
<div className="active-ads-ads-arrows">
<button onClick={activeAdsArrowLeftHandler}>
<img src={arrow_left} alt="arrow-left" />
</button>
<button onClick={activeAdsArrowRightHandler}>
<img src={arrow_right} alt="arrow-right" />
</button>
</div>
)}
</div>
<Slider {...settings} style={{ width: "100%" }} ref={adsSliderRef}>
{candidate.ads.map((add, index) => (
<CandidateAd
add={add}
key={index}
onclick={() => navigateToDetailsPage(add.id)}
className={index === 0 ? "" : "proba2"}
/> />
<div className="applicant-add-site">dilig.net</div>
</div>
))}
))}
{candidate.ads.length <= 5 && getDummyAds(candidate.ads.length)}
</Slider>
</div> </div>
</div> </div>
<div className="applicant-ads-buttons-container"> <div className="applicant-ads-buttons-container">
); );
}; };


CandidateDetailsPage.propTypes = {
history: PropTypes.shape({
replace: PropTypes.func,
push: PropTypes.func,
location: PropTypes.shape({
pathname: PropTypes.string,
}),
}),
};

export default CandidateDetailsPage; export default CandidateDetailsPage;

+ 213
- 41
src/pages/CandidatesPage/CandidatesPage.js Просмотреть файл

import IconButton from "../../components/IconButton/IconButton"; import IconButton from "../../components/IconButton/IconButton";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { fetchCandidates } from "../../store/actions/candidates/candidatesActions";
import {
fetchAdsCandidates,
filterCandidates,
} from "../../store/actions/candidates/candidatesActions";
import tableImage from "../../assets/images/table.png"; import tableImage from "../../assets/images/table.png";
import modeImage from "../../assets/images/mode.png";
import adImage from "../../assets/images/.net_icon.png";
import filterImage from "../../assets/images/filters.png"; import filterImage from "../../assets/images/filters.png";
import { formatDate } from "../../util/helpers/dateHelpers"; import { formatDate } from "../../util/helpers/dateHelpers";
import planeImage from "../../assets/images/planeVector.png"; import planeImage from "../../assets/images/planeVector.png";
import arrow_left from "../../assets/images/arrow_left.png";
import arrow_right from "../../assets/images/arrow_right.png";
import { useMediaQuery } from "@mui/material"; import { useMediaQuery } from "@mui/material";
import { useTheme } from "@mui/system"; import { useTheme } from "@mui/system";
import { CANDIDATES_PAGE } from "../../constants/pages"; import { CANDIDATES_PAGE } from "../../constants/pages";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Slider from "react-slick";
import CandidateCard from "../../components/Candidates/CandidateCard";
import useDynamicRefs from "use-dynamic-refs";
import CandidateFilters from "../../components/Candidates/CandidateFilters";
import Pagination from "@mui/material/Pagination";
import { PAGE_SIZE_CANDIDATES } from "../../constants/keyCodeConstants";


const CandidatesPage = ({ history }) => { const CandidatesPage = ({ history }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { candidates } = useSelector((s) => s.candidates); const { candidates } = useSelector((s) => s.candidates);
const { pagination } = useSelector((s) => s.candidates); // pagination is total number of candidates on backend
const { adsCandidates } = useSelector((s) => s.candidates);
const theme = useTheme(); const theme = useTheme();
const matches = useMediaQuery(theme.breakpoints.down("sm")); const matches = useMediaQuery(theme.breakpoints.down("sm"));
const [isTableView, setIsTableView] = useState(true); const [isTableView, setIsTableView] = useState(true);
const [getRef, setRef] = useDynamicRefs();
const [toggleFiltersDrawer, setToggleFiltersDrawer] = useState(false);
const [page, setPage] = React.useState(1);


useEffect(() => { useEffect(() => {
dispatch(fetchCandidates());
dispatch(
filterCandidates({
currentPage: page,
pageSize: PAGE_SIZE_CANDIDATES,
minExperience: 0,
maxExperience: 0,
employmentType: "",
minDateOfApplication: "",
maxDateOfApplication: "",
technologies: [],
})
);
dispatch(fetchAdsCandidates());
}, [dispatch]); }, [dispatch]);


const navigate = (applicantId) => { const navigate = (applicantId) => {


const changeView = () => { const changeView = () => {
setIsTableView(!isTableView); setIsTableView(!isTableView);
}
};

const handleToggleFiltersDrawer = () => {
setToggleFiltersDrawer((oldState) => !oldState);
};

var settings = {
dots: false,
infinite: false,
speed: 400,
slidesToShow: 4,
slidesToScroll: 4,
initialSlide: 0,
arrows: true,
variableWidth: true,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: false,
},
},
{
breakpoint: 900,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
initialSlide: 0,
},
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
},
},
],
};

const getDummyCandidates = (len) => {
const candidates = [];

for (let i = 0; i < 4 - len + 1; i++) {
candidates.push(
<CandidateCard key={i} className="hiddenAd" history={history} />
);
}

return candidates;
};

const activeAdsArrowLeftHandler = (index) => {
getRef(index.toString()).current.slickPrev();
};

const activeAdsArrowRightHandler = (index) => {
getRef(index.toString()).current.slickNext();
};

const handleChange = (event, value) => {
dispatch(
filterCandidates({
currentPage: value,
pageSize: PAGE_SIZE_CANDIDATES,
minExperience: 0,
maxExperience: 5,
employmentType: "Intership",
minDateOfApplication: "10/05/2020",
maxDateOfApplication: "10/10/2022",
technologies: [],
})
);
setPage(value);
};


return candidates[0] === undefined ? (
<p>Loading...</p>
) : (
return (
<div className="main-candidates-container pl-144 pt-36px"> <div className="main-candidates-container pl-144 pt-36px">
<CandidateFilters
open={toggleFiltersDrawer}
handleClose={handleToggleFiltersDrawer}
pageSize={PAGE_SIZE_CANDIDATES}
currentPage={page}
/>
<div className="l-t-rectangle"></div> <div className="l-t-rectangle"></div>
<div className="r-b-rectangle"></div> <div className="r-b-rectangle"></div>
<div className="top-candidates-container"> <div className="top-candidates-container">
)} )}
<div className="candidates-options-container"> <div className="candidates-options-container">
{!matches ? ( {!matches ? (
<IconButton className="c-btn c-btn--primary-outlined candidate-btn" onClick={changeView}>
Tablicni prikaz
<img src={tableImage} alt="table" className="candidates-image" />
</IconButton>
isTableView ? (
<IconButton
className="c-btn c-btn--primary-outlined candidate-btn all-white-btn"
onClick={changeView}
>
Tablicni prikaz
<img
src={tableImage}
alt="table"
className="candidates-image"
/>
</IconButton>
) : (
<IconButton
className="c-btn c-btn--primary-outlined candidate-btn"
onClick={changeView}
>
Tablicni prikaz
<img
src={tableImage}
alt="table"
className="candidates-image"
/>
</IconButton>
)
) : ( ) : (
<IconButton className="c-btn--primary-outlined c-btn candidate-btn-mobile"> <IconButton className="c-btn--primary-outlined c-btn candidate-btn-mobile">
<img <img
</IconButton> </IconButton>
)} )}
{!matches ? ( {!matches ? (
<IconButton className="c-btn c-btn--primary-outlined candidate-btn">
Rezim uredjivanja
<img
src={modeImage}
alt="mode of editing"
className="candidates-image"
/>
</IconButton>
) : (
<IconButton className="c-btn c-btn--primary-outlined candidate-btn-mobile">
<img
src={modeImage}
className="candidate-image-mobile"
alt="mode of editing"
/>
</IconButton>
)}
{!matches ? (
<IconButton className="c-btn c-btn--primary-outlined candidate-btn">
<IconButton
className="c-btn c-btn--primary-outlined candidate-btn"
onClick={handleToggleFiltersDrawer}
>
Filteri Filteri
<img <img
src={filterImage} src={filterImage}
/> />
</IconButton> </IconButton>
) : ( ) : (
<IconButton className="c-btn c-btn--primary-outlined candidate-btn-mobile">
<IconButton
className="c-btn c-btn--primary-outlined candidate-btn-mobile"
onClick={handleToggleFiltersDrawer}
>
<img <img
src={filterImage} src={filterImage}
alt="filter" alt="filter"
)} )}
</div> </div>
</div> </div>
<div className="candidates-table">
{isTableView ? (
{isTableView ? (
<div className="candidates-table">
<table <table
className="usersTable" className="usersTable"
style={{ width: "1117px", height: "100px" }} style={{ width: "1117px", height: "100px" }}
))} ))}
</tbody> </tbody>
</table> </table>
) : (
<p>Table view disabled</p>
)}
<IconButton className="c-btn candidate-btn invite-btn invite-btn-color">
<img src={planeImage} alt="table" className="candidates-image" />
Invite
</IconButton>
</div>
<Pagination
count={
parseInt(pagination) <= PAGE_SIZE_CANDIDATES
? 1
: Math.ceil(parseInt(pagination) / PAGE_SIZE_CANDIDATES)
}
color="primary"
style={{ alignSelf: "center", marginTop: "20px" }}
onChange={handleChange}
shape="rounded"
/>
</div>
) : (
<div className="ads-candidates-container proba">
{adsCandidates.map((adCandidates, index) => (
<div className="ads-candidates" key={index}>
<div className="ads-candidates-top-container">
<img src={adImage} style={{ width: "49px", height: "39px" }} />
<p className="ads-candidates-title">{adCandidates.title}</p>
<p className="ads-candidates-numberOfApplicants">
| {adCandidates.nubmerOfApplicants} prijavljenih
</p>
</div>
<div
className="ads-candidates-slider"
style={{ display: "flex", marginTop: "31px" }}
>
{adCandidates.applicants.length > 3 && (
<div className="active-ads-ads-arrows">
<button onClick={() => activeAdsArrowLeftHandler(index)}>
<img src={arrow_left} alt="arrow-left" />
</button>
<button onClick={() => activeAdsArrowRightHandler(index)}>
<img src={arrow_right} alt="arrow-right" />
</button>
</div>
)}
<Slider
{...settings}
ref={setRef(index.toString())}
style={{ width: "100%" }}
>
{adCandidates.applicants.map((candidate, index) => (
<CandidateCard
key={index}
candidate={candidate}
history={history}
className={index === 0 ? "" : "proba2"}
/>
))}
{adCandidates.applicants.length <= 4 &&
getDummyCandidates(adCandidates.applicants.length)}
</Slider>
</div>
</div>
))}
</div>
)}
<IconButton className="c-btn candidate-btn invite-btn invite-btn-color">
<img src={planeImage} alt="table" className="candidates-image" />
Invite
</IconButton>
</div> </div>
); );
}; };

+ 2
- 1
src/request/apiEndpoints.js Просмотреть файл

invite:'http://localhost:26081/v1/users/invite', invite:'http://localhost:26081/v1/users/invite',
}, },
candidates: { candidates: {
allCandidates: base + "/applicants",
filteredCandidates:base + "/applicants",
allAdsCandidates: base + "/applicants/adsApplicants"
}, },
ads: { ads: {
allAds: base + "/ads", allAds: base + "/ads",

+ 34
- 4
src/request/candidatesRequest.js Просмотреть файл

import { getRequest, postRequest } from ".";
import { deleteRequest, getRequest, postRequest } from ".";
import apiEndpoints from "./apiEndpoints"; import apiEndpoints from "./apiEndpoints";


export const getAllCandidates = () => getRequest(apiEndpoints.candidates.allCandidates)
export const getCandidate = (id) => getRequest(apiEndpoints.candidates.allCandidates + "/" + id)
export const createComment = (data) => postRequest(apiEndpoints.comments.addComment,data)
export const getFilteredCandidates = (payload) => {
let technologiesQuery = "";
for (let i = 0; i < payload.technologies.length; i++) {
technologiesQuery += `technologies=${payload.technologies[i]}&`;
}
return getRequest(
apiEndpoints.candidates.filteredCandidates +
"?currentPage=" +
payload.currentPage +
"&pageSize=" +
payload.pageSize +
"&minExperience=" +
payload.minExperience +
"&maxExperience=" +
payload.maxExperience +
"&employmentType=" +
payload.employmentType +
"&minDateOfApplication=" +
payload.minDateOfApplication +
"&maxDateOfApplication=" +
payload.maxDateOfApplication +
"&" +
technologiesQuery
);
};
export const getCandidate = (id) =>
getRequest(apiEndpoints.candidates.filteredCandidates + "/" + id);
export const createComment = (data) =>
postRequest(apiEndpoints.comments.addComment, data);
export const getAllAdsCandidates = () =>
getRequest(apiEndpoints.candidates.allAdsCandidates);
export const deleteCandidate = (id) =>
deleteRequest(apiEndpoints.candidates.allCandidates + "?id=" + id);

+ 36
- 19
src/store/actions/candidate/candidateActionConstants.js Просмотреть файл

import { import {
createErrorType,
createFetchType,
createLoadingType,
createSuccessType,
} from "../actionHelpers";
const CANDIDATE_SCOPE = 'CANDIDATE'
const CANDIDATE_SCOPE_COMMENTS = 'CANDIDATE_COMMENTS'
export const CANDIDATE_FETCH = createFetchType(CANDIDATE_SCOPE);
export const CANDIDATE_ERROR = createErrorType(CANDIDATE_SCOPE)
export const CANDIDATE_SUCCESS = createSuccessType(CANDIDATE_SCOPE)
export const CANDIDATE_LOADING = createLoadingType(CANDIDATE_SCOPE)
export const CANDIDATE_COMMENTS_FETCH = createFetchType(CANDIDATE_SCOPE_COMMENTS);
export const CANDIDATE_COMMENTS_ERROR = createErrorType(CANDIDATE_SCOPE_COMMENTS)
export const CANDIDATE_COMMENTS_SUCCESS = createSuccessType(CANDIDATE_SCOPE_COMMENTS)
export const CANDIDATE_COMMENTS_LOADING = createLoadingType(CANDIDATE_SCOPE_COMMENTS)
createErrorType,
createFetchType,
createLoadingType,
createSuccessType,
} from "../actionHelpers";

const CANDIDATE_SCOPE = "CANDIDATE";
const CANDIDATE_SCOPE_COMMENTS = "CANDIDATE_COMMENTS";
const DELETE_CANDIDATE_SCOPE = "DELETE_CANDIDATE";

export const CANDIDATE_FETCH = createFetchType(CANDIDATE_SCOPE);
export const CANDIDATE_ERROR = createErrorType(CANDIDATE_SCOPE);
export const CANDIDATE_SUCCESS = createSuccessType(CANDIDATE_SCOPE);
export const CANDIDATE_LOADING = createLoadingType(CANDIDATE_SCOPE);

export const CANDIDATE_COMMENTS_FETCH = createFetchType(
CANDIDATE_SCOPE_COMMENTS
);
export const CANDIDATE_COMMENTS_ERROR = createErrorType(
CANDIDATE_SCOPE_COMMENTS
);
export const CANDIDATE_COMMENTS_SUCCESS = createSuccessType(
CANDIDATE_SCOPE_COMMENTS
);
export const CANDIDATE_COMMENTS_LOADING = createLoadingType(
CANDIDATE_SCOPE_COMMENTS
);

export const DELETE_CANDIDATE = createFetchType(DELETE_CANDIDATE_SCOPE);
export const DELETE_CANDIDATE_ERROR = createErrorType(DELETE_CANDIDATE_SCOPE);
export const DELETE_CANDIDATE_SUCCESS = createSuccessType(
DELETE_CANDIDATE_SCOPE
);
export const DELETE_CANDIDATE_LOADING = createLoadingType(
DELETE_CANDIDATE_SCOPE
);

+ 17
- 0
src/store/actions/candidate/candidateActions.js Просмотреть файл

CANDIDATE_COMMENTS_FETCH, CANDIDATE_COMMENTS_FETCH,
CANDIDATE_COMMENTS_ERROR, CANDIDATE_COMMENTS_ERROR,
CANDIDATE_COMMENTS_SUCCESS, CANDIDATE_COMMENTS_SUCCESS,
DELETE_CANDIDATE,
DELETE_CANDIDATE_ERROR,
DELETE_CANDIDATE_SUCCESS,
} from "./candidateActionConstants"; } from "./candidateActionConstants";


export const fetchCandidate = (payload) => ({ export const fetchCandidate = (payload) => ({
type: CANDIDATE_COMMENTS_SUCCESS, type: CANDIDATE_COMMENTS_SUCCESS,
payload, payload,
}); });

export const deleteCandidate = (payload) => ({
type: DELETE_CANDIDATE,
payload,
});

export const deleteCandidateError = (payload) => ({
type: DELETE_CANDIDATE_ERROR,
payload,
});

export const deleteCandidateSuccess = () => ({
type: DELETE_CANDIDATE_SUCCESS
});

+ 12
- 5
src/store/actions/candidates/candidatesActionConstants.js Просмотреть файл

createSuccessType, createSuccessType,
} from "../actionHelpers"; } from "../actionHelpers";


const CANDIDATES_SCOPE = 'CANDIDATES'
const ADS_CANDIDATES_SCOPE = "ADS_CANDIDATES";
const FILTER_CANDIDATES_SCOPE = "FILTER_CANDIDATES";

export const FILTER_CANDIDATES = createFetchType(FILTER_CANDIDATES_SCOPE);
export const FILTER_CANDIDATES_ERROR = createErrorType(FILTER_CANDIDATES_SCOPE);
export const FILTER_CANDIDATES_SUCCESS = createSuccessType(FILTER_CANDIDATES_SCOPE);
export const FILTER_CANDIDATES_LOADING = createLoadingType(FILTER_CANDIDATES_SCOPE);

export const ADS_CANDIDATES_FETCH = createFetchType(ADS_CANDIDATES_SCOPE);
export const ADS_CANDIDATES_ERROR = createErrorType(ADS_CANDIDATES_SCOPE);
export const ADS_CANDIDATES_SUCCESS = createSuccessType(ADS_CANDIDATES_SCOPE);
export const ADS_CANDIDATES_LOADING = createLoadingType(ADS_CANDIDATES_SCOPE);


export const CANDIDATES_FETCH = createFetchType(CANDIDATES_SCOPE);
export const CANDIDATES_ERROR = createErrorType(CANDIDATES_SCOPE)
export const CANDIDATES_SUCCESS = createSuccessType(CANDIDATES_SCOPE)
export const CANDIDATES_LOADING = createLoadingType(CANDIDATES_SCOPE)

+ 26
- 9
src/store/actions/candidates/candidatesActions.js Просмотреть файл

import { import {
CANDIDATES_FETCH,
CANDIDATES_ERROR,
CANDIDATES_SUCCESS,
ADS_CANDIDATES_FETCH,
ADS_CANDIDATES_ERROR,
ADS_CANDIDATES_SUCCESS,
FILTER_CANDIDATES,
FILTER_CANDIDATES_ERROR,
FILTER_CANDIDATES_SUCCESS,
} from './candidatesActionConstants'; } from './candidatesActionConstants';
export const fetchCandidates = () => ({
type: CANDIDATES_FETCH,
export const filterCandidates = (payload) => ({
type: FILTER_CANDIDATES,
payload
}); });


export const fetchCandidatesError = (payload) => ({
type: CANDIDATES_ERROR,
export const filterCandidatesError = (payload) => ({
type: FILTER_CANDIDATES_ERROR,
payload, payload,
}); });
export const fetchCandidatesSuccess = (payload) => ({
type: CANDIDATES_SUCCESS,
export const filterCandidatesSuccess = (payload) => ({
type: FILTER_CANDIDATES_SUCCESS,
payload, payload,
}); });


export const fetchAdsCandidates = () => ({
type: ADS_CANDIDATES_FETCH,
});

export const fetchAdsCandidatesError = (payload) => ({
type: ADS_CANDIDATES_ERROR,
payload,
});
export const fetchAdsCandidatesSuccess = (payload) => ({
type: ADS_CANDIDATES_SUCCESS,
payload,
});

+ 19
- 0
src/store/reducers/candidate/candidateReducer.js Просмотреть файл

CANDIDATE_SUCCESS, CANDIDATE_SUCCESS,
CANDIDATE_COMMENTS_SUCCESS, CANDIDATE_COMMENTS_SUCCESS,
CANDIDATE_COMMENTS_ERROR, CANDIDATE_COMMENTS_ERROR,
DELETE_CANDIDATE_SUCCESS,
DELETE_CANDIDATE_ERROR
} from "../../actions/candidate/candidateActionConstants"; } from "../../actions/candidate/candidateActionConstants";


const initialState = { const initialState = {
[CANDIDATE_ERROR]: setError, [CANDIDATE_ERROR]: setError,
[CANDIDATE_COMMENTS_SUCCESS]: setComments, [CANDIDATE_COMMENTS_SUCCESS]: setComments,
[CANDIDATE_COMMENTS_ERROR]: setCommentsError, [CANDIDATE_COMMENTS_ERROR]: setCommentsError,
[DELETE_CANDIDATE_SUCCESS]:deleteCandidate,
[DELETE_CANDIDATE_ERROR]:deleteCandidateError
}, },
initialState initialState
); );
errorMessage: action.payload, errorMessage: action.payload,
}; };
} }

function deleteCandidate(state) {
return {
...state,
candidate: {},
};
}


function deleteCandidateError(state, action) {
return {
...state,
errorMessage: action.payload,
};
}

+ 31
- 8
src/store/reducers/candidates/candidatesReducer.js Просмотреть файл

import createReducer from "../../utils/createReducer"; import createReducer from "../../utils/createReducer";
import { import {
CANDIDATES_ERROR,
CANDIDATES_SUCCESS,
ADS_CANDIDATES_ERROR,
ADS_CANDIDATES_SUCCESS,
FILTER_CANDIDATES_SUCCESS,
FILTER_CANDIDATES_ERROR
} from "../../actions/candidates/candidatesActionConstants"; } from "../../actions/candidates/candidatesActionConstants";


const initialState = { const initialState = {
candidates: [], candidates: [],
adsCandidates: [],
errorMessage: "", errorMessage: "",
pagination: 0,
}; };


export default createReducer( export default createReducer(
{ {
[CANDIDATES_SUCCESS]: setCandidates,
[CANDIDATES_ERROR]: setError
[FILTER_CANDIDATES_SUCCESS]: filterCandidates,
[FILTER_CANDIDATES_ERROR]: setFilterCandidatesError,
[ADS_CANDIDATES_SUCCESS]: setAdsCandidates,
[ADS_CANDIDATES_ERROR]: setAdsCandidatesError,
}, },
initialState initialState
); );


function setCandidates(state, action) {
function filterCandidates(state, action) {
let m = action.payload;
let t = m.pop();
return { return {
...state, ...state,
candidates: action.payload,
candidates: m,
pagination: t,
}; };
} }


function setError(state, action) {
function setFilterCandidatesError(state, action) {
return { return {
...state, ...state,
errorMessage: action.payload, errorMessage: action.payload,
}; };
}
}

function setAdsCandidates(state, action) {
return {
...state,
adsCandidates: action.payload,
};
}

function setAdsCandidatesError(state, action) {
return {
...state,
errorMessage: action.payload,
};
}

+ 82
- 23
src/store/saga/candidatesSaga.js Просмотреть файл

import { all, call, put, takeEvery } from "redux-saga/effects"; import { all, call, put, takeEvery } from "redux-saga/effects";
import { JWT_TOKEN } from "../../constants/localStorage"; import { JWT_TOKEN } from "../../constants/localStorage";
import { addHeaderToken } from "../../request"; import { addHeaderToken } from "../../request";
import { getAllCandidates,createComment,getCandidate } from "../../request/candidatesRequest";
import {
createComment,
getCandidate,
getAllAdsCandidates,
deleteCandidate,
getFilteredCandidates
} from "../../request/candidatesRequest";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers"; import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { CANDIDATES_FETCH} from "../actions/candidates/candidatesActionConstants";
import { fetchCandidatesError,fetchCandidatesSuccess } from "../actions/candidates/candidatesActions";
import { rejectErrorCodeHelper } from '../../util/helpers/rejectErrorCodeHelper';
import { fetchCandidateError, fetchCandidateSuccess,createCandidateCommentSuccess,createCandidateCommentError } from "../actions/candidate/candidateActions";
import { CANDIDATE_FETCH,CANDIDATE_COMMENTS_FETCH } from "../actions/candidate/candidateActionConstants";
import {
ADS_CANDIDATES_FETCH,
FILTER_CANDIDATES
} from "../actions/candidates/candidatesActionConstants";
import {
fetchAdsCandidatesError,
fetchAdsCandidatesSuccess,
filterCandidatesSuccess,
filterCandidatesError,
} from "../actions/candidates/candidatesActions";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";
import {
fetchCandidateError,
fetchCandidateSuccess,
createCandidateCommentSuccess,
createCandidateCommentError,
deleteCandidateSuccess,
deleteCandidateError,
} from "../actions/candidate/candidateActions";
import {
CANDIDATE_FETCH,
CANDIDATE_COMMENTS_FETCH,
DELETE_CANDIDATE,
} from "../actions/candidate/candidateActionConstants";
import { CANDIDATES_PAGE } from "../../constants/pages";
import history from "../utils/history";


export function* getCandidates() {

export function* filterCandidates({ payload }) {
try { try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken); yield call(addHeaderToken, JwtToken);
const {data} = yield call(getAllCandidates);
yield put(fetchCandidatesSuccess(data));
const response = yield call(getFilteredCandidates,payload);
let data = response.data;
const pagination = response.headers.pagination;
data.push(pagination)
yield put(filterCandidatesSuccess(data));
if(payload.handleApiResponseSuccess){
yield call(payload.handleApiResponseSuccess)
}
} catch (error) { } catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error); const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(fetchCandidatesError(errorMessage))
yield put(filterCandidatesError(errorMessage));
} }
} }


export function* getSingleCandidate({payload}){
try{
export function* getSingleCandidate({ payload }) {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken); yield call(addHeaderToken, JwtToken);
const {data} = yield call(getCandidate,payload.id)
yield put(fetchCandidateSuccess(data))
} catch(error){
const { data } = yield call(getCandidate, payload.id);
yield put(fetchCandidateSuccess(data));
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error); const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(fetchCandidateError(errorMessage))
yield put(fetchCandidateError(errorMessage));
} }
} }


export function* addComment(data) { export function* addComment(data) {
const {user,...myObj} = data.payload
try{
const { user, ...myObj } = data.payload;
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken); yield call(addHeaderToken, JwtToken);
yield call(createComment,myObj);
yield put(createCandidateCommentSuccess({user,myObj}))
} catch (error){
yield call(createComment, myObj);
yield put(createCandidateCommentSuccess({ user, myObj }));
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(createCandidateCommentError(errorMessage));
}
}

export function* getAdsCandidates() {
try {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
const { data } = yield call(getAllAdsCandidates);
yield put(fetchAdsCandidatesSuccess(data));
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(fetchAdsCandidatesError(errorMessage));
}
}

export function* deleteSingleCandidate({ payload }) {
try {
yield call(deleteCandidate, payload.id);
yield call(history.replace, CANDIDATES_PAGE);
yield put(deleteCandidateSuccess());
} catch (error) {
const errorMessage = yield call(rejectErrorCodeHelper, error); const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(createCandidateCommentError(errorMessage))
yield put(deleteCandidateError(errorMessage));
} }
} }


export default function* candidatesSaga() { export default function* candidatesSaga() {
yield all([takeEvery(CANDIDATES_FETCH, getCandidates)]);
yield all([takeEvery(CANDIDATE_FETCH, getSingleCandidate)]); yield all([takeEvery(CANDIDATE_FETCH, getSingleCandidate)]);
yield all([takeEvery(ADS_CANDIDATES_FETCH, getAdsCandidates)]);
yield all([takeEvery(CANDIDATE_COMMENTS_FETCH, addComment)]); yield all([takeEvery(CANDIDATE_COMMENTS_FETCH, addComment)]);
yield all([takeEvery(DELETE_CANDIDATE, deleteSingleCandidate)]);
yield all([takeEvery(FILTER_CANDIDATES, filterCandidates)]);
} }

+ 3
- 7
src/store/selectors/candidatesSelectors.js Просмотреть файл

import { createSelector } from "@reduxjs/toolkit";

export const candidatesSelector = (state) => state.candidates;

export const selectCandidates = createSelector(
candidatesSelector,
(state) => state.candidates,
export const selectAdsCandidates = createSelector(
adsCandidatesSelector,
(state) => state.adsCandidates,
); );

+ 5
- 0
src/util/helpers/dateHelpers.js Просмотреть файл

return format(dt, fmt, { locale }); return format(dt, fmt, { locale });
} }


export function formatDateInput(date, fmt = 'y-MM-dd', locale = enUS) {
const dt = new Date(date);
return format(dt, fmt, { locale });
}

export function formatDateTime(date) { export function formatDateTime(date) {
const dt = new Date(date); const dt = new Date(date);
return format(dt, 'hh:mm dd.MM.y'); return format(dt, 'hh:mm dd.MM.y');

+ 66
- 51
yarn.lock Просмотреть файл

"resolved" "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz" "resolved" "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz"
"version" "7.14.4" "version" "7.14.4"


"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.4":
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.1.0", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0", "@babel/core@^7.7.5", "@babel/core@^7.8.4", "@babel/core@7 || ^7.0.0-rc.2":
"integrity" "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==" "integrity" "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg=="
"resolved" "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz" "resolved" "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz"
"version" "7.14.3" "version" "7.14.3"
"resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz" "resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz"
"version" "0.8.0" "version" "0.8.0"


"@emotion/react@^11.1.1", "@emotion/react@^11.5.0":
"@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.1.1", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0":
"integrity" "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==" "integrity" "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA=="
"resolved" "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz" "resolved" "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz"
"version" "11.10.4" "version" "11.10.4"
dependencies: dependencies:
"@babel/runtime" "^7.19.0" "@babel/runtime" "^7.19.0"


"@mui/material@^5.0.6":
"@mui/material@^5.0.0", "@mui/material@^5.0.6", "@mui/material@^5.4.1":
"integrity" "sha512-ioLvqY7VvcePz9dnEIRhpiVvtJmAFmvG6rtLXXzVdMmAVbSaelr5Io07mPz/mCyqE+Uv8/4EuJV276DWO7etzA==" "integrity" "sha512-ioLvqY7VvcePz9dnEIRhpiVvtJmAFmvG6rtLXXzVdMmAVbSaelr5Io07mPz/mCyqE+Uv8/4EuJV276DWO7etzA=="
"resolved" "https://registry.npmjs.org/@mui/material/-/material-5.10.10.tgz" "resolved" "https://registry.npmjs.org/@mui/material/-/material-5.10.10.tgz"
"version" "5.10.10" "version" "5.10.10"
"csstype" "^3.1.1" "csstype" "^3.1.1"
"prop-types" "^15.8.1" "prop-types" "^15.8.1"


"@mui/system@^5.10.10":
"@mui/system@^5.10.10", "@mui/system@^5.4.1":
"integrity" "sha512-TXwtKN0adKpBrZmO+eilQWoPf2veh050HLYrN78Kps9OhlvO70v/2Kya0+mORFhu9yhpAwjHXO8JII/R4a5ZLA==" "integrity" "sha512-TXwtKN0adKpBrZmO+eilQWoPf2veh050HLYrN78Kps9OhlvO70v/2Kya0+mORFhu9yhpAwjHXO8JII/R4a5ZLA=="
"resolved" "https://registry.npmjs.org/@mui/system/-/system-5.10.10.tgz" "resolved" "https://registry.npmjs.org/@mui/system/-/system-5.10.10.tgz"
"version" "5.10.10" "version" "5.10.10"
dependencies: dependencies:
"defer-to-connect" "^1.0.1" "defer-to-connect" "^1.0.1"


"@testing-library/dom@^8.0.0":
"@testing-library/dom@^8.0.0", "@testing-library/dom@>=7.21.4":
"integrity" "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==" "integrity" "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A=="
"resolved" "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz" "resolved" "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz"
"version" "8.19.0" "version" "8.19.0"
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"


"@types/react@*":
"@types/react@*", "@types/react@^17.0.0 || ^18.0.0":
"integrity" "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==" "integrity" "sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA=="
"resolved" "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz" "resolved" "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz"
"version" "18.0.21" "version" "18.0.21"
"@types/source-list-map" "*" "@types/source-list-map" "*"
"source-map" "^0.7.3" "source-map" "^0.7.3"


"@types/webpack@^4.41.8":
"@types/webpack@^4.41.8", "@types/webpack@4.x":
"integrity" "sha512-6pLaORaVNZxiB3FSHbyBiWM7QdazAWda1zvAq4SbZObZqHSDbWLi62iFdblVea6SK9eyBIVp5yHhKt/yNQdR7Q==" "integrity" "sha512-6pLaORaVNZxiB3FSHbyBiWM7QdazAWda1zvAq4SbZObZqHSDbWLi62iFdblVea6SK9eyBIVp5yHhKt/yNQdR7Q=="
"resolved" "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.29.tgz" "resolved" "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.29.tgz"
"version" "4.41.29" "version" "4.41.29"
dependencies: dependencies:
"@types/yargs-parser" "*" "@types/yargs-parser" "*"


"@typescript-eslint/eslint-plugin@^4.5.0":
"@typescript-eslint/eslint-plugin@^4.0.0", "@typescript-eslint/eslint-plugin@^4.5.0", "@typescript-eslint/eslint-plugin@>= 4":
"integrity" "sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==" "integrity" "sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg=="
"resolved" "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz" "resolved" "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.0.tgz"
"version" "4.26.0" "version" "4.26.0"
"eslint-scope" "^5.1.1" "eslint-scope" "^5.1.1"
"eslint-utils" "^3.0.0" "eslint-utils" "^3.0.0"


"@typescript-eslint/parser@^4.5.0":
"@typescript-eslint/parser@^4.0.0", "@typescript-eslint/parser@^4.5.0":
"integrity" "sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg==" "integrity" "sha512-b4jekVJG9FfmjUfmM4VoOItQhPlnt6MPOBUL0AQbiTmm+SSpSdhHYlwayOm4IW9KLI/4/cRKtQCmDl1oE2OlPg=="
"resolved" "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz" "resolved" "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.0.tgz"
"version" "4.26.0" "version" "4.26.0"
"resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" "resolved" "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz"
"version" "7.2.0" "version" "7.2.0"


"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^7.1.0", "acorn@^7.1.1", "acorn@^7.4.0":
"integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
"version" "7.4.1"

"acorn@^6.4.1": "acorn@^6.4.1":
"integrity" "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" "integrity" "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz" "resolved" "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz"
"version" "6.4.2" "version" "6.4.2"


"acorn@^7.1.0", "acorn@^7.1.1", "acorn@^7.4.0":
"integrity" "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
"version" "7.4.1"

"acorn@^8.2.4": "acorn@^8.2.4":
"integrity" "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==" "integrity" "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw=="
"resolved" "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz" "resolved" "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz"
"resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" "resolved" "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz"
"version" "3.5.2" "version" "3.5.2"


"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.4", "ajv@^6.12.5":
"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.4", "ajv@^6.12.5", "ajv@^6.9.1", "ajv@>=5.0.0":
"integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" "integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" "resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
"version" "6.12.6" "version" "6.12.6"
"resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" "resolved" "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz"
"version" "2.2.0" "version" "2.2.0"


"babel-eslint@^10.1.0":
"babel-eslint@^10.0.0", "babel-eslint@^10.1.0":
"integrity" "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==" "integrity" "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg=="
"resolved" "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz" "resolved" "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz"
"version" "10.1.0" "version" "10.1.0"
dependencies: dependencies:
"pako" "~1.0.5" "pako" "~1.0.5"


"browserslist@^4.0.0", "browserslist@^4.12.0", "browserslist@^4.16.6", "browserslist@^4.6.2", "browserslist@^4.6.4":
"browserslist@^4", "browserslist@^4.0.0", "browserslist@^4.12.0", "browserslist@^4.16.6", "browserslist@^4.6.2", "browserslist@^4.6.4":
"integrity" "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==" "integrity" "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ=="
"resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz" "resolved" "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz"
"version" "4.16.6" "version" "4.16.6"
"lodash" "^4.17.15" "lodash" "^4.17.15"
"string-natural-compare" "^3.0.1" "string-natural-compare" "^3.0.1"


"eslint-plugin-import@^2.22.1", "eslint-plugin-import@^2.23.4":
"eslint-plugin-import@^2.22.0", "eslint-plugin-import@^2.22.1", "eslint-plugin-import@^2.23.4":
"integrity" "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==" "integrity" "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ=="
"resolved" "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz" "resolved" "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz"
"version" "2.23.4" "version" "2.23.4"
"resolve" "^1.20.0" "resolve" "^1.20.0"
"tsconfig-paths" "^3.9.0" "tsconfig-paths" "^3.9.0"


"eslint-plugin-jest@^24.1.0":
"eslint-plugin-jest@^24.0.0", "eslint-plugin-jest@^24.1.0":
"integrity" "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==" "integrity" "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg=="
"resolved" "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz" "resolved" "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz"
"version" "24.3.6" "version" "24.3.6"
dependencies: dependencies:
"prettier-linter-helpers" "^1.0.0" "prettier-linter-helpers" "^1.0.0"


"eslint-plugin-react-hooks@^4.2.0":
"eslint-plugin-react-hooks@^4 || ^3 || ^2.3.0 || ^1.7.0", "eslint-plugin-react-hooks@^4.0.8", "eslint-plugin-react-hooks@^4.2.0":
"integrity" "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==" "integrity" "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ=="
"resolved" "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz" "resolved" "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz"
"version" "4.2.0" "version" "4.2.0"


"eslint-plugin-react@^7.21.5", "eslint-plugin-react@^7.24.0":
"eslint-plugin-react@^7.20.3", "eslint-plugin-react@^7.21.5", "eslint-plugin-react@^7.24.0":
"integrity" "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==" "integrity" "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q=="
"resolved" "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz" "resolved" "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz"
"version" "7.24.0" "version" "7.24.0"
dependencies: dependencies:
"safe-regex" "^1.1.0" "safe-regex" "^1.1.0"


"eslint-plugin-testing-library@^3.9.2":
"eslint-plugin-testing-library@^3.9.0", "eslint-plugin-testing-library@^3.9.2":
"integrity" "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==" "integrity" "sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA=="
"resolved" "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz" "resolved" "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-3.10.2.tgz"
"version" "3.10.2" "version" "3.10.2"
"normalize-path" "^3.0.0" "normalize-path" "^3.0.0"
"schema-utils" "^3.0.0" "schema-utils" "^3.0.0"


"eslint@^7.11.0", "eslint@^7.28.0":
"eslint@*", "eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0", "eslint@^3 || ^4 || ^5 || ^6 || ^7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "eslint@^5 || ^6 || ^7", "eslint@^5.0.0 || ^6.0.0 || ^7.0.0", "eslint@^5.16.0 || ^6.8.0 || ^7.2.0", "eslint@^7.0.0", "eslint@^7.1.0", "eslint@^7.11.0", "eslint@^7.28.0", "eslint@^7.5.0", "eslint@>= 4.12.1", "eslint@>=5", "eslint@>=5.0.0", "eslint@>=7.0.0":
"integrity" "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==" "integrity" "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA=="
"resolved" "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" "resolved" "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz"
"version" "7.32.0" "version" "7.32.0"
dependencies: dependencies:
"flat-cache" "^3.0.4" "flat-cache" "^3.0.4"


"file-loader@6.1.1":
"file-loader@*", "file-loader@6.1.1":
"integrity" "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw==" "integrity" "sha512-Klt8C4BjWSXYQAfhpYYkG4qHNTna4toMHEbWrI5IuVoxbU6uiDKeKAP99R8mmbJi3lvewn/jQBOgU4+NS3tDQw=="
"resolved" "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz" "resolved" "https://registry.npmjs.org/file-loader/-/file-loader-6.1.1.tgz"
"version" "6.1.1" "version" "6.1.1"
"resolved" "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" "resolved" "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz"
"version" "1.1.1" "version" "1.1.1"


"i18next@^20.3.1":
"i18next@^20.3.1", "i18next@>= 19.0.0":
"integrity" "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==" "integrity" "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A=="
"resolved" "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz" "resolved" "https://registry.npmjs.org/i18next/-/i18next-20.6.1.tgz"
"version" "20.6.1" "version" "20.6.1"
"jest-regex-util" "^26.0.0" "jest-regex-util" "^26.0.0"
"jest-snapshot" "^26.6.2" "jest-snapshot" "^26.6.2"


"jest-resolve@^26.6.2":
"integrity" "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ=="
"resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz"
"version" "26.6.2"
"jest-resolve@*", "jest-resolve@26.6.0":
"integrity" "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ=="
"resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz"
"version" "26.6.0"
dependencies: dependencies:
"@jest/types" "^26.6.2"
"@jest/types" "^26.6.0"
"chalk" "^4.0.0" "chalk" "^4.0.0"
"graceful-fs" "^4.2.4" "graceful-fs" "^4.2.4"
"jest-pnp-resolver" "^1.2.2" "jest-pnp-resolver" "^1.2.2"
"jest-util" "^26.6.2"
"jest-util" "^26.6.0"
"read-pkg-up" "^7.0.1" "read-pkg-up" "^7.0.1"
"resolve" "^1.18.1"
"resolve" "^1.17.0"
"slash" "^3.0.0" "slash" "^3.0.0"


"jest-resolve@26.6.0":
"integrity" "sha512-tRAz2bwraHufNp+CCmAD8ciyCpXCs1NQxB5EJAmtCFy6BN81loFEGWKzYu26Y62lAJJe4X4jg36Kf+NsQyiStQ=="
"resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.0.tgz"
"version" "26.6.0"
"jest-resolve@^26.6.2":
"integrity" "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ=="
"resolved" "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz"
"version" "26.6.2"
dependencies: dependencies:
"@jest/types" "^26.6.0"
"@jest/types" "^26.6.2"
"chalk" "^4.0.0" "chalk" "^4.0.0"
"graceful-fs" "^4.2.4" "graceful-fs" "^4.2.4"
"jest-pnp-resolver" "^1.2.2" "jest-pnp-resolver" "^1.2.2"
"jest-util" "^26.6.0"
"jest-util" "^26.6.2"
"read-pkg-up" "^7.0.1" "read-pkg-up" "^7.0.1"
"resolve" "^1.17.0"
"resolve" "^1.18.1"
"slash" "^3.0.0" "slash" "^3.0.0"


"jest-runner@^26.6.0", "jest-runner@^26.6.3": "jest-runner@^26.6.0", "jest-runner@^26.6.3":
"merge-stream" "^2.0.0" "merge-stream" "^2.0.0"
"supports-color" "^7.0.0" "supports-color" "^7.0.0"


"jest@^26.6.0", "jest@26.6.0":
"jest@^26.0.0", "jest@^26.6.0", "jest@26.6.0":
"integrity" "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA==" "integrity" "sha512-jxTmrvuecVISvKFFhOkjsWRZV7sFqdSUAd1ajOKY+/QE/aLBVstsJ/dX8GczLzwiT6ZEwwmZqtCUHLHHQVzcfA=="
"resolved" "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz" "resolved" "https://registry.npmjs.org/jest/-/jest-26.6.0.tgz"
"version" "26.6.0" "version" "26.6.0"
"resolved" "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz" "resolved" "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz"
"version" "1.4.0" "version" "1.4.0"


"jquery@>=1.8.0":
"integrity" "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
"resolved" "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz"
"version" "3.6.1"

"js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0": "js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0":
"integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" "integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
"resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" "resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
dependencies: dependencies:
"fast-diff" "^1.1.2" "fast-diff" "^1.1.2"


"prettier@2.3.1":
"prettier@>=1.13.0", "prettier@2.3.1":
"integrity" "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==" "integrity" "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA=="
"resolved" "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz" "resolved" "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz"
"version" "2.3.1" "version" "2.3.1"
"strip-ansi" "6.0.0" "strip-ansi" "6.0.0"
"text-table" "0.2.0" "text-table" "0.2.0"


"react-dom@^17.0.2":
"react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@^17.0.2 || ^18.0.0", "react-dom@<18.0.0", "react-dom@>=16.6.0", "react-dom@>=16.8.3":
"integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" "integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
"version" "17.0.2" "version" "17.0.2"
"prop-types" "^15.5.8" "prop-types" "^15.5.8"
"substyle" "^9.1.0" "substyle" "^9.1.0"


"react-redux@^7.2.4":
"react-redux@^7.2.1 || ^8.0.2", "react-redux@^7.2.4":
"integrity" "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==" "integrity" "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ=="
"resolved" "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz" "resolved" "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz"
"version" "7.2.9" "version" "7.2.9"
"prop-types" "^15.7.2" "prop-types" "^15.7.2"
"react-is" "^17.0.2" "react-is" "^17.0.2"


"react-refresh@^0.8.3":
"react-refresh@^0.8.3", "react-refresh@>=0.8.3 <0.10.0":
"integrity" "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" "integrity" "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg=="
"resolved" "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz" "resolved" "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz"
"version" "0.8.3" "version" "0.8.3"
"loose-envify" "^1.4.0" "loose-envify" "^1.4.0"
"prop-types" "^15.6.2" "prop-types" "^15.6.2"


"react@^17.0.2":
"react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.0.0", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.0 || ^17.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", "react@^17.0.2", "react@^17.0.2 || ^18.0.0", "react@^18.2.0", "react@<18.0.0", "react@>= 16", "react@>= 16.8.0", "react@>=15", "react@>=16.6.0", "react@>=16.8.0", "react@>=16.8.3", "react@17.0.2":
"integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" "integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA=="
"resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" "resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
"version" "17.0.2" "version" "17.0.2"
"resolved" "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz" "resolved" "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz"
"version" "2.4.1" "version" "2.4.1"


"redux@^4.0.0", "redux@^4.0.4", "redux@^4.1.0", "redux@^4.1.2":
"redux@^4", "redux@^4.0.0", "redux@^4.0.4", "redux@^4.1.0", "redux@^4.1.2":
"integrity" "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==" "integrity" "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA=="
"resolved" "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz" "resolved" "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz"
"version" "4.2.0" "version" "4.2.0"
dependencies: dependencies:
"estree-walker" "^0.6.1" "estree-walker" "^0.6.1"


"rollup@^1.31.1":
"rollup@^1.20.0 || ^2.0.0", "rollup@^1.20.0||^2.0.0", "rollup@^1.31.1", "rollup@>=0.60.0 <3", "rollup@>=0.66.0 <3":
"integrity" "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==" "integrity" "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A=="
"resolved" "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz" "resolved" "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz"
"version" "1.32.1" "version" "1.32.1"
"schema-utils" "^3.0.0" "schema-utils" "^3.0.0"
"semver" "^7.3.2" "semver" "^7.3.2"


"sass@^1.34.1":
"sass@^1.3.0", "sass@^1.34.1":
"integrity" "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==" "integrity" "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A=="
"resolved" "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz" "resolved" "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz"
"version" "1.55.0" "version" "1.55.0"
"source-map-resolve" "^0.5.0" "source-map-resolve" "^0.5.0"
"use" "^3.1.0" "use" "^3.1.0"


"sockjs-client@^1.5.0":
"sockjs-client@^1.4.0", "sockjs-client@^1.5.0":
"integrity" "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==" "integrity" "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ=="
"resolved" "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz" "resolved" "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz"
"version" "1.5.1" "version" "1.5.1"
dependencies: dependencies:
"typescript-compare" "^0.0.2" "typescript-compare" "^0.0.2"


"typescript@^3.2.1 || ^4", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta":
"integrity" "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA=="
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz"
"version" "4.9.3"

"unbox-primitive@^1.0.2": "unbox-primitive@^1.0.2":
"integrity" "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==" "integrity" "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw=="
"resolved" "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" "resolved" "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"
"punycode" "1.3.2" "punycode" "1.3.2"
"querystring" "0.2.0" "querystring" "0.2.0"


"use-dynamic-refs@^1.0.0":
"integrity" "sha512-1Ky+Jaj6MIpTRz6NTaCLVm/iDXfRNwUMH9X7BkLtgSL2RCXHQhK2p9SVhut8jZPDfxLDtOIYNM3txsiLXd4yVQ=="
"resolved" "https://registry.npmjs.org/use-dynamic-refs/-/use-dynamic-refs-1.0.0.tgz"
"version" "1.0.0"

"use@^3.1.0": "use@^3.1.0":
"integrity" "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" "integrity" "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
"resolved" "https://registry.npmjs.org/use/-/use-3.1.1.tgz" "resolved" "https://registry.npmjs.org/use/-/use-3.1.1.tgz"
"range-parser" "^1.2.1" "range-parser" "^1.2.1"
"webpack-log" "^2.0.0" "webpack-log" "^2.0.0"


"webpack-dev-server@3.11.1":
"webpack-dev-server@3.11.1", "webpack-dev-server@3.x":
"integrity" "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==" "integrity" "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ=="
"resolved" "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz" "resolved" "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz"
"version" "3.11.1" "version" "3.11.1"
"source-list-map" "^2.0.0" "source-list-map" "^2.0.0"
"source-map" "~0.6.1" "source-map" "~0.6.1"


"webpack@4.44.2":
"webpack@^4.0.0", "webpack@^4.0.0 || ^5.0.0", "webpack@^4.27.0 || ^5.0.0", "webpack@^4.36.0 || ^5.0.0", "webpack@^4.4.0 || ^5.0.0", "webpack@>=2", "webpack@>=4.43.0 <6.0.0", "webpack@2 || 3 || 4", "webpack@4.44.2":
"integrity" "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q==" "integrity" "sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q=="
"resolved" "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz" "resolved" "https://registry.npmjs.org/webpack/-/webpack-4.44.2.tgz"
"version" "4.44.2" "version" "4.44.2"

Загрузка…
Отмена
Сохранить