diff --git a/package-lock.json b/package-lock.json index f1711533..159d1760 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1129,11 +1129,87 @@ "resolved": "https://registry.npmjs.org/@date-io/core/-/core-1.3.13.tgz", "integrity": "sha512-AlEKV7TxjeK+jxWVKcCFrfYAk8spX9aCyiToFIiLPtfQbsjmRGLIhb5VZgptQcJdHtLXo7+m0DuurwFgUToQuA==" }, + "@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "requires": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + } + }, + "@emotion/core": { + "version": "10.0.28", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz", + "integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==", + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + } + }, + "@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "requires": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + } + }, "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==" + }, + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1717,6 +1793,14 @@ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz", "integrity": "sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA==" }, + "@tinymce/tinymce-react": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@tinymce/tinymce-react/-/tinymce-react-3.6.0.tgz", + "integrity": "sha512-XSyAx9Md9+Ghl3UK0YtBQxaS2dCepqtOKTjYmBS4xTAzSu1UABd44WT84B8CUCd/bdT0fv1Pd51dSbpgJ8713w==", + "requires": { + "prop-types": "^15.6.2" + } + }, "@types/babel__core": { "version": "7.1.8", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", @@ -1759,6 +1843,19 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha512-cfBw6q6tT5sa1gSPFSRKzF/xxYrrmeiut7E0TxNBObiLSBTuFEHibcfEe3waQPEDbqBsq+ql/TOniw65EyDFMA==" + }, + "@types/domutils": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@types/domutils/-/domutils-1.7.2.tgz", + "integrity": "sha512-Nnwy1Ztwq42SSNSZSh9EXBJGrOZPR+PQ2sRT4VZy8hnsFXfCil7YlKO2hd2360HyrtFz2qwnKQ13ENrgXNxJbw==", + "requires": { + "@types/domhandler": "*" + } + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1773,6 +1870,16 @@ "@types/node": "*" } }, + "@types/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@types/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-fCxmHS4ryCUCfV9+CJZY1UjkbR+6Al/EQdX5Jh03qBj9gdlPG5q+7uNoDgE/ZNXb3XNWSAQgqKIWnbRCbOyyWA==", + "requires": { + "@types/domhandler": "*", + "@types/domutils": "*", + "@types/node": "*" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -2215,6 +2322,11 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "a11y-focus-store": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/a11y-focus-store/-/a11y-focus-store-1.0.0.tgz", + "integrity": "sha1-rlJWHLhq5sKQTBpKvy5YIL9TBbA=" + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -2357,6 +2469,11 @@ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, + "animation-bus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/animation-bus/-/animation-bus-0.2.0.tgz", + "integrity": "sha1-Q4VMLJRj+4LGZO/w4ZuXMwgRUPo=" + }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", @@ -2426,6 +2543,14 @@ "sprintf-js": "~1.0.2" } }, + "aria-hidden": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.1.1.tgz", + "integrity": "sha512-M7zYxCcOQPOaxGHoMTKUFD2UNcVFTp9ycrdStLcTPLf8zgTXC3+YcGe+UuzSh5X1BX/0/PtS8xTNy4xyH/6xtw==", + "requires": { + "tslib": "^1.0.0" + } + }, "aria-query": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.0.tgz", @@ -2608,6 +2733,11 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, + "attr-accept": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.1.0.tgz", + "integrity": "sha512-sLzVM3zCCmmDtDNhI0i96k6PUztkotSOXqE4kDGQt/6iDi5M+H0srjeF+QC6jN581l4X/Zq3Zu/tgcErEssavg==" + }, "autoprefixer": { "version": "9.8.0", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", @@ -2746,6 +2876,30 @@ "object.assign": "^4.1.0" } }, + "babel-plugin-emotion": { + "version": "10.0.33", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz", + "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } + } + }, "babel-plugin-istanbul": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", @@ -2864,6 +3018,11 @@ "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.6.tgz", "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==" }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", @@ -3258,6 +3417,11 @@ "resolved": "https://registry.npmjs.org/boostrap/-/boostrap-2.0.0.tgz", "integrity": "sha512-JEeFMOweKeGXEM9rt95eaVISOkluG9aKcl0jQCETOVH9jynCZxuBZe2oWgcWJpj5wqYWZl625SnW7OgHT2Ineg==" }, + "bowser": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz", + "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4141,6 +4305,52 @@ "sha.js": "^2.4.8" } }, + "cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "requires": { + "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", @@ -4227,6 +4437,15 @@ } } }, + "css-in-js-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", + "requires": { + "hyphenate-style-name": "^1.0.2", + "isobject": "^3.0.1" + } + }, "css-loader": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", @@ -4940,6 +5159,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -5912,6 +6139,35 @@ "bser": "2.1.1" } }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + } + } + }, "figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -5942,6 +6198,14 @@ "schema-utils": "^2.5.0" } }, + "file-selector": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.1.12.tgz", + "integrity": "sha512-Kx7RTzxyQipHuiqyZGf+Nz4vY9R1XGxuQl/hLoJwq+J4avk/9wxxgZyHKtbyIPJmbD4A66DWGYfyykWNpcYutQ==", + "requires": { + "tslib": "^1.9.0" + } + }, "filesize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", @@ -6002,6 +6266,11 @@ "pkg-dir": "^3.0.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -6049,6 +6318,11 @@ "readable-stream": "^2.3.6" } }, + "focus-lock": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.7.0.tgz", + "integrity": "sha512-LI7v2mH02R55SekHYdv9pRHR9RajVNyIJ2N5IEkWbg7FT5ZmJ9Hw4mWxHeEUcd+dJo0QmzztHvDvWcc7prVFsw==" + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -6161,6 +6435,11 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fscreen": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fscreen/-/fscreen-1.0.2.tgz", + "integrity": "sha1-xMUdltgZ11oZ1yjg30Rfm+m7mE8=" + }, "fsevents": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", @@ -6221,11 +6500,21 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-own-enumerable-property-symbols": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" }, + "get-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-prefix/-/get-prefix-1.0.0.tgz", + "integrity": "sha1-DTBUSKTjF2+cJ3F1sU4W2+b7oLU=" + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -6252,6 +6541,15 @@ "assert-plus": "^1.0.0" } }, + "glam": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/glam/-/glam-5.0.1.tgz", + "integrity": "sha512-NCnYcPpefXJMH30LaUfKKP3BkpipI9jkeOvzMZAd76cuDxfKmQRBvgQ1LxXRj9IRZVAwl0K3WQvbw+tiyK2pcw==", + "requires": { + "fbjs": "^0.8.16", + "inline-style-prefixer": "^3.0.8" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -6594,6 +6892,16 @@ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" }, + "html-dom-parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-0.3.0.tgz", + "integrity": "sha512-WDEYpO5gHGKuJbf0rwndGq7yUHJ4xboNj9l9mRGw5RsKFc3jfRozCsGAMu69zXxt4Ol8UkbqubKxu8ys0BLKtA==", + "requires": { + "@types/domhandler": "2.4.1", + "domhandler": "2.4.2", + "htmlparser2": "3.10.1" + } + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -6633,6 +6941,17 @@ } } }, + "html-react-parser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-0.13.0.tgz", + "integrity": "sha512-hU94hE2p9xhMM61EOoiY3Kr+DfzH/uY7hGeVXQpGFRjgbYRUeyuSKORDNMIaY8IAcuHQ6Ov9pJ3x94Wvso/OmQ==", + "requires": { + "@types/htmlparser2": "3.10.1", + "html-dom-parser": "0.3.0", + "react-property": "1.0.1", + "style-to-object": "0.3.0" + } + }, "html-webpack-plugin": { "version": "4.0.0-beta.11", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz", @@ -6884,6 +7203,20 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "inline-style-prefixer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz", + "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=", + "requires": { + "bowser": "^1.7.3", + "css-in-js-utils": "^2.0.0" + } + }, "inquirer": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", @@ -7304,6 +7637,15 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -8242,6 +8584,14 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, + "linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -8480,6 +8830,18 @@ "object-visit": "^1.0.0" } }, + "markdown-it": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-11.0.0.tgz", + "integrity": "sha512-+CvOnmbSubmQFSA9dKz1BRiaSMV7rhexl3sngKqFyXSagoA3fBdJQ8oZWtRy2knXdpDXaBw44euz37DeJQ9asg==", + "requires": { + "argparse": "^1.0.7", + "entities": "~2.0.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, "matchmediaquery": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.3.1.tgz", @@ -8503,6 +8865,11 @@ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -8788,6 +9155,11 @@ "through2": "^2.0.0" } }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==" + }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -8932,6 +9304,15 @@ "tslib": "^1.10.0" } }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, "node-forge": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", @@ -10944,6 +11325,11 @@ "performance-now": "^2.1.0" } }, + "raf-schd": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-2.1.2.tgz", + "integrity": "sha512-Orl0IEvMtUCgPddgSxtxreK77UiQz4nPYJy9RggVzu4mKsZkQWiAaG1y9HlYWdvm9xtN348xRaT37qkvL/+A+g==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11034,6 +11420,14 @@ "warning": "^4.0.3" } }, + "react-clientside-effect": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.2.tgz", + "integrity": "sha512-nRmoyxeok5PBO6ytPvSjKp9xwXg9xagoTK1mMjwnQxqM9Hd7MNPl+LS1bOSOe+CV2+4fnEquc7H/S8QD3q697A==", + "requires": { + "@babel/runtime": "^7.0.0" + } + }, "react-content-loader": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/react-content-loader/-/react-content-loader-5.0.4.tgz", @@ -11323,11 +11717,56 @@ "scheduler": "^0.19.1" } }, + "react-dropzone": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-11.0.1.tgz", + "integrity": "sha512-x/6wqRHaR8jsrNiu/boVMIPYuoxb83Vyfv77hO7/3ZRn8Pr+KH5onsCsB8MLBa3zdJl410C5FXPUINbu16XIzw==", + "requires": { + "attr-accept": "^2.0.0", + "file-selector": "^0.1.12", + "prop-types": "^15.7.2" + } + }, "react-error-overlay": { "version": "6.0.7", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.7.tgz", "integrity": "sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA==" }, + "react-focus-lock": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.4.0.tgz", + "integrity": "sha512-mue/boxdfNhfxnQcZtEBvqwZ5XQxk0uRoAMwLGl8j6XolFV3UIlt6iGFBGqRdJsvVHhtyKC5i8fkLnBidxCTbA==", + "requires": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^0.7.0", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.2", + "use-callback-ref": "^1.2.1", + "use-sidecar": "^1.0.1" + } + }, + "react-focus-on": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.4.1.tgz", + "integrity": "sha512-KGRIl0iAu+1k1dcX7eQCXF5ZR/nl+XyXN5Ukw/OY80vLaK2b6vDzNqnX0HdYbY5xSUhIRUvMWEzSsdEyPjvk/Q==", + "requires": { + "aria-hidden": "^1.1.1", + "react-focus-lock": "^2.3.1", + "react-remove-scroll": "^2.3.0", + "react-style-singleton": "^2.1.0", + "use-callback-ref": "^1.2.3", + "use-sidecar": "^1.0.1" + } + }, + "react-full-screen": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/react-full-screen/-/react-full-screen-0.2.4.tgz", + "integrity": "sha512-K6V87g/uopQnnebg6/jM7VL3FcurgCIQU4nTkzknbjGOT9XOOxr3XVwRweI8QPn1TFRZH7j5OpHanUdk5uYlBQ==", + "requires": { + "@types/react": "*", + "fscreen": "^1.0.1" + } + }, "react-icons": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.10.0.tgz", @@ -11343,6 +11782,64 @@ } } }, + "react-images": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/react-images/-/react-images-1.1.7.tgz", + "integrity": "sha512-9paR4bdP/SPTbJ/8cLa6+7+pcq8PGN4/8UjTfztQKBRzGxH0BtHrB7oj/7As2RmYMkOsVIMNfDaWzZZK4faIRA==", + "requires": { + "a11y-focus-store": "^1.0.0", + "cross-env": "^7.0.2", + "glam": "^5.0.1", + "html-react-parser": "^0.10.3", + "raf-schd": "^2.1.2", + "react-focus-on": "^3.3.0", + "react-full-screen": "^0.2.4", + "react-transition-group": "^2.9.0", + "react-view-pager": "^0.6.0" + }, + "dependencies": { + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "html-dom-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-0.2.3.tgz", + "integrity": "sha512-GdzE63/U0IQEvcpAz0cUdYx2zQx0Ai+HWvE9TXEgwP27+SymUzKa7iB4DhjYpf2IdNLfTTOBuMS5nxeWOosSMQ==", + "requires": { + "@types/domhandler": "2.4.1", + "domhandler": "2.4.2", + "htmlparser2": "3.10.1" + } + }, + "html-react-parser": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-0.10.5.tgz", + "integrity": "sha512-rtMWZ7KZjd9sO8jyIX7am0vGCIL45tCmctTnassT/BrTGeTaAZ4nQyqoGcx2v+vB8CAY+Q5PZiiV6eOiowq8dQ==", + "requires": { + "@types/domhandler": "2.4.1", + "html-dom-parser": "0.2.3", + "react-property": "1.0.1", + "style-to-object": "0.3.0" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -11362,6 +11859,28 @@ "lottie-web": "^5.1.3" } }, + "react-markdown-editor-lite": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/react-markdown-editor-lite/-/react-markdown-editor-lite-1.1.4.tgz", + "integrity": "sha512-DnHa3e1CBax+34MKr75Bt9UPyC7PEItV16qGh59zU9YBxrISupOUwzN5oh6LLXp0uv8WrRdzyPLo3c7dHmNfKg==" + }, + "react-motion": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz", + "integrity": "sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==", + "requires": { + "performance-now": "^0.2.0", + "prop-types": "^15.5.8", + "raf": "^3.1.0" + }, + "dependencies": { + "performance-now": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=" + } + } + }, "react-overlays": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-3.2.0.tgz", @@ -11377,6 +11896,11 @@ "warning": "^4.0.3" } }, + "react-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-1.0.1.tgz", + "integrity": "sha512-1tKOwxFn3dXVomH6pM9IkLkq2Y8oh+fh/lYW3MJ/B03URswUTqttgckOlbxY2XHF3vPG6uanSc4dVsLW/wk3wQ==" + }, "react-redux": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz", @@ -11389,6 +11913,27 @@ "react-is": "^16.9.0" } }, + "react-remove-scroll": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.3.0.tgz", + "integrity": "sha512-UqVimLeAe+5EHXKfsca081hAkzg3WuDmoT9cayjBegd6UZVhlTEchleNp9J4TMGkb/ftLve7ARB5Wph+HJ7A5g==", + "requires": { + "react-remove-scroll-bar": "^2.1.0", + "react-style-singleton": "^2.1.0", + "tslib": "^1.0.0", + "use-callback-ref": "^1.2.3", + "use-sidecar": "^1.0.1" + } + }, + "react-remove-scroll-bar": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.1.0.tgz", + "integrity": "sha512-5X5Y5YIPjIPrAoMJxf6Pfa7RLNGCgwZ95TdnVPgPuMftRfO8DaC7F4KP1b5eiO8hHbe7u+wZNDbYN5WUTpv7+g==", + "requires": { + "react-style-singleton": "^2.1.0", + "tslib": "^1.0.0" + } + }, "react-responsive": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.1.0.tgz", @@ -11511,6 +12056,24 @@ } } }, + "react-spinners": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/react-spinners/-/react-spinners-0.8.3.tgz", + "integrity": "sha512-fuYNjH0megp5FLuUqQXWM9mPgBXUjvYD6IkMOiwNGOOlI2UdOP1ZC3vejUAa3Y/q4qWJ6yx8rjfMjIBgEji+9A==", + "requires": { + "@emotion/core": "^10.0.15" + } + }, + "react-style-singleton": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.1.0.tgz", + "integrity": "sha512-DH4ED+YABC1dhvSDYGGreAHmfuTXj6+ezT3CmHoqIEfxNgEYfIMoOtmbRp42JsUst3IPqBTDL+8r4TF7EWhIHw==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^1.0.0" + } + }, "react-toastify": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-6.0.5.tgz", @@ -11519,6 +12082,19 @@ "classnames": "^2.2.6", "prop-types": "^15.7.2", "react-transition-group": "^4.4.1" + }, + "dependencies": { + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + } } }, "react-transition-group": { @@ -11532,6 +12108,19 @@ "prop-types": "^15.6.2" } }, + "react-view-pager": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-view-pager/-/react-view-pager-0.6.0.tgz", + "integrity": "sha512-nV6VTLyHmv4T9QszZVD3sRn3EcUKgb2NhSdz9kjTIpzE+SwOl4mfcQtqUwc6St3EnMtus805zVJ8OcSjFEqhpg==", + "requires": { + "animation-bus": "^0.2.0", + "get-prefix": "^1.0.0", + "mitt": "1.1.3", + "react-motion": "^0.5.0", + "resize-observer-polyfill": "1.5.0", + "tabbable": "1.1.2" + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -11846,6 +12435,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" }, + "resize-observer-polyfill": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz", + "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==" + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -13103,6 +13697,14 @@ } } }, + "style-to-object": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", + "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, "stylehacks": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", @@ -13168,6 +13770,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "tabbable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-1.1.2.tgz", + "integrity": "sha512-77oqsKEPrxIwgRcXUwipkj9W5ItO97L6eUT1Ar7vh+El16Zm4M6V+YU1cbipHEa6q0Yjw8O3Hoh8oRgatV5s7A==" + }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -13662,6 +14269,16 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "ua-parser-js": { + "version": "0.7.21", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", + "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "uncontrollable": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz", @@ -13843,6 +14460,20 @@ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, + "use-callback-ref": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.4.tgz", + "integrity": "sha512-rXpsyvOnqdScyied4Uglsp14qzag1JIemLeTWGKbwpotWht57hbP78aNT+Q4wdFKQfQibbUX4fb6Qb4y11aVOQ==" + }, + "use-sidecar": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.2.tgz", + "integrity": "sha512-287RZny6m5KNMTb/Kq9gmjafi7lQL0YHO1lYolU6+tY1h9+Z3uCtkJJ3OSOq3INwYf2hBryCcDh4520AhJibMA==", + "requires": { + "detect-node": "^2.0.4", + "tslib": "^1.9.3" + } + }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", diff --git a/package.json b/package.json index 156c5233..92342149 100644 --- a/package.json +++ b/package.json @@ -10,21 +10,28 @@ "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.4.0", "@testing-library/user-event": "^7.2.1", + "@tinymce/tinymce-react": "^3.6.0", "axios": "^0.19.1", "boostrap": "^2.0.0", + "html-react-parser": "^0.13.0", "jwt-decode": "^2.2.0", + "markdown-it": "^11.0.0", "node-sass": "^4.13.0", "react": "^16.12.0", "react-bootstrap": "^1.0.0-beta.16", "react-content-loader": "^5.0.4", "react-cookies": "^0.1.1", "react-dom": "^16.12.0", + "react-dropzone": "^11.0.1", "react-icons": "^3.9.0", + "react-images": "^1.1.7", "react-lottie": "^1.2.3", + "react-markdown-editor-lite": "^1.1.4", "react-redux": "^7.2.0", "react-responsive": "^8.0.3", "react-router-dom": "^5.1.2", "react-scripts": "^3.4.0", + "react-spinners": "^0.8.3", "react-toastify": "^6.0.5", "redux": "^4.0.5", "redux-thunk": "^2.3.0", diff --git a/src/actions/notificationAction.js b/src/actions/notificationAction.js index 7059e299..f2a7c2a2 100644 --- a/src/actions/notificationAction.js +++ b/src/actions/notificationAction.js @@ -1,41 +1,63 @@ -import { GET_PLATFORM_NOTIFICATIONS, GET_USER_NOTIFICATIONS } from './types' -import axios from 'axios' -import { errorHandler } from '../utils/errorHandler'; -import { setRequestStatus } from '../utils/setRequestStatus'; +import { + GET_PLATFORM_NOTIFICATIONS, + GET_USER_NOTIFICATIONS, + GET_PROPOSAL_NOTIFICATIONS, +} from "./types"; +import axios from "axios"; +import { errorHandler } from "../utils/errorHandler"; +import { setRequestStatus } from "../utils/setRequestStatus"; // GET NOTIFICATIONS FOR WHOLE PLATFORM AS WELL AS FOR A USER export const getAllNotifications = () => async (dispatch) => { try { - const res = await axios.get('/notification/org/all') - dispatch(setRequestStatus(false)) + const res = await axios.get("/notification/org/all"); + dispatch(setRequestStatus(false)); if (res.status === 200) { - dispatch(setRequestStatus(true)) - console.log('Whole platform notification ', res.data.notifications) + dispatch(setRequestStatus(true)); + console.log("Whole platform notification ", res.data.notifications); dispatch({ type: GET_PLATFORM_NOTIFICATIONS, - payload: res.data.notifications - }) + payload: res.data.notifications, + }); } } catch (error) { - dispatch(errorHandler(error)) + dispatch(errorHandler(error)); } -} +}; // GET NOTIFICATIONS FOR A USER export const getUserNotification = () => async (dispatch) => { try { - const res = await axios.get('/notification/user/all') - dispatch(setRequestStatus(false)) + const res = await axios.get("/notification/user/all"); + dispatch(setRequestStatus(false)); if (res.status === 200) { - dispatch(setRequestStatus(true)) - console.log('User notification ', res.data.notifications) + dispatch(setRequestStatus(true)); + console.log("User notification ", res.data.notifications); dispatch({ type: GET_USER_NOTIFICATIONS, - payload: res.data.notifications - }) + payload: res.data.notifications, + }); } } catch (error) { - dispatch(errorHandler(error)) + dispatch(errorHandler(error)); } -} +}; + +// GET PROPOSAL NOTIFICATIONS +export const getProposalNotifications = () => async (dispatch) => { + try { + const res = await axios.get("/notification/proposal/all"); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + console.log("Proposal notification ", res.data.notifications); + dispatch({ + type: GET_PROPOSAL_NOTIFICATIONS, + payload: res.data.notifications, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; diff --git a/src/actions/proposalActions.js b/src/actions/proposalActions.js new file mode 100644 index 00000000..fb783acc --- /dev/null +++ b/src/actions/proposalActions.js @@ -0,0 +1,159 @@ +import axios from "axios"; +import { errorHandler } from "../utils/errorHandler"; +import { setRequestStatus } from "../utils/setRequestStatus"; +import { + CREATE_PROPOSAL, + GET_PROPOSAL, + GET_USER_PROPOSAL_NOTIFICATIONS, + GET_ALL_PROPOSALS, + GET_USER_PROPOSALS, +} from "../actions/types"; + +// CREATE PROPOSAL +export const createProposal = (proposalInfo) => async (dispatch) => { + try { + const res = await axios.post("/proposal", proposalInfo); + dispatch(setRequestStatus(false)); + if (res.status === 201) { + dispatch(setRequestStatus(true)); + console.log("proposal created in ACTION", res.data); + dispatch({ + type: CREATE_PROPOSAL, + payload: res.data.proposal || res.data.msg, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// GET PROPOSAL DATA +export const getProposal = (proposalId) => async (dispatch) => { + try { + const res = await axios.get("/proposal/" + proposalId); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + console.log("proposal data fetched in action", res.data); + dispatch({ + type: GET_PROPOSAL, + payload: res.data.proposal || res.data.msg, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// SAVE PROPOSAL DATA +export const saveProposal = (proposalData) => async (dispatch) => { + try { + const res = await axios.patch( + "/proposal/" + proposalData.proposalId, + proposalData + ); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// SUBMIT PROPOSAL +export const submitProposal = (proposalData) => async (dispatch) => { + console.log(proposalData); + try { + const res = await axios.patch( + "/proposal/change/" + proposalData.proposalId, + proposalData + ); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// DELETE PROPOSAL +export const deleteProposal = (proposalId) => async (dispatch) => { + try { + const res = await axios.delete("/proposal", { + headers: {}, + data: { proposalId: proposalId }, + }); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// COMMENT ON PROPOSAL +export const commentProposal = (commentData) => async (dispatch) => { + try { + const res = await axios.post("/proposal/comment", commentData); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// GET USER RELATED PROPOSAL NOTIFICATIONS +export const getUserProposalNotifications = (data) => async (dispatch) => { + try { + const res = await axios.post("/proposal/notifications", data); + console.log(res); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + dispatch({ + type: GET_USER_PROPOSAL_NOTIFICATIONS, + payload: res.data.proposal || res.data.msg, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// GET ALL PROPOSALS +export const getAllProposals = () => async (dispatch) => { + try { + const res = await axios.post("/proposal/all"); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + dispatch({ + type: GET_ALL_PROPOSALS, + payload: res.data.proposals || res.data.msg, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; + +// GET PROPOSALS BY USER ID +export const getProposalsByUser = (userId) => async (dispatch) => { + try { + const res = await axios.get(`/proposal/user/${userId}`); + dispatch(setRequestStatus(false)); + if (res.status === 200) { + dispatch(setRequestStatus(true)); + dispatch({ + type: GET_USER_PROPOSALS, + payload: res.data.proposal || res.data.msg, + }); + } + } catch (error) { + dispatch(errorHandler(error)); + } +}; diff --git a/src/actions/types.js b/src/actions/types.js index cdcbc38d..8f945bdc 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -1,12 +1,14 @@ -export const GET_CURRENT_USER = "GET_CURRENT_USER"; -export const SET_CURRENT_USER = "SET_CURRENT_USER"; -export const RESPONSE_MSG = "RESPONSE_MSG"; +export const GET_CURRENT_USER = "GET_CURRENT_USER"; +export const SET_CURRENT_USER = "SET_CURRENT_USER"; +export const RESPONSE_MSG = "RESPONSE_MSG"; export const GET_ERRORS = "GET_ERRORS"; export const SET_ERROR = "SET_ERROR"; export const SET_STATUS = "SET_STATUS"; export const GET_PLATFORM_NOTIFICATIONS = "GET_PLATFORM_NOTIFICATIONS"; export const GET_USER_NOTIFICATIONS = "GET_USER_NOTIFICATIONS"; -export const GET_ALL_NOTIFICATIONS = "GET_ALL_NOTIFICATIONS"; +export const GET_PROPOSAL_NOTIFICATIONS = "GET_PROPOSAL_NOTIFICATIONS"; +export const GET_USER_PROPOSAL_NOTIFICATIONS = + "GET_USER_PROPOSAL_NOTIFICATIONS"; export const SET_ADMIN = "SET_ADMIN"; export const GET_ALL_UPCOMING_EVENTS = "GET_ALL_UPCOMING_EVENTS"; export const GET_ALL_MEMBERS = "GET_ALL_MEMBERS"; @@ -27,12 +29,18 @@ export const GET_ALL_EVENTS = "GET_ALL_EVENTS"; export const GET_ALL_PROJECTS = "GET_ALL_PROJECTS"; export const GET_ALL_POSTS = "GET_ALL_POSTS"; export const GET_USER_POSTS = "GET_USER_POSTS"; +export const CREATE_PROPOSAL = "CREATE_PROPOSAL"; +export const GET_PROPOSAL = "GET_PROPOSAL"; +export const GET_ALL_PROPOSALS = "GET_ALL_PROPOSALS"; +export const EXIT = "EXIT"; +export const GET_USER_PROPOSALS = "GET USER PROPOSALS"; export const GET_ALL_PINNED_POSTS = "GET_ALL_PINNED_POSTS"; export const GET_EVENT_BY_ID = "GET_EVENT_BY_ID"; export const GET_ADMIN = "GET_ADMIN"; export const GET_COMMENTS_OF_A_POST = "GET_COMMENTS_OF_A_POST"; export const GET_SINGLE_PROJECT = "GET_SINGLE_PROJECT"; -export const PASSWORD_CHANGE_REQUEST_SUCCESS = "PASSWORD_CHANGE_REQUEST_SUCCESS"; +export const PASSWORD_CHANGE_REQUEST_SUCCESS = + "PASSWORD_CHANGE_REQUEST_SUCCESS"; export const PASSWORD_SUCCESSFULLY_CHANGED = "PASSWORD_SUCCESSFULLY_CHANGED"; export const GET_INVITE_LINK = "GET_INVITE_LINK"; -export const PROCESS_INVITE_LINK = "PROCESS_INVITE_LINK"; \ No newline at end of file +export const PROCESS_INVITE_LINK = "PROCESS_INVITE_LINK"; diff --git a/src/reducers/index.js b/src/reducers/index.js index 250d51d9..0d50fe5a 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,17 +1,18 @@ -import { combineReducers } from 'redux'; -import authReducers from './authReducer'; -import postReducers from './postReducer'; -import userReducers from './userReducer'; -import errorReducer from './errorReducer'; -import requestStatus from './requestStatus'; -import notificationReducer from './notificationReducer' -import dashboardReducer from './dashboardReducer' -import insightReducer from './insightReducer'; -import orgReducer from './orgReducer'; -import eventReducer from './eventReducer'; -import projectReducer from './projectReducer'; -import adminReducers from './adminReducers'; -import commentReducer from './commentReducer'; +import { combineReducers } from "redux"; +import authReducers from "./authReducer"; +import postReducers from "./postReducer"; +import userReducers from "./userReducer"; +import errorReducer from "./errorReducer"; +import requestStatus from "./requestStatus"; +import notificationReducer from "./notificationReducer"; +import dashboardReducer from "./dashboardReducer"; +import insightReducer from "./insightReducer"; +import orgReducer from "./orgReducer"; +import eventReducer from "./eventReducer"; +import projectReducer from "./projectReducer"; +import proposalReducer from "./proposalReducer"; +import adminReducers from "./adminReducers"; +import commentReducer from "./commentReducer"; const rootReducer = combineReducers({ auth: authReducers, @@ -24,9 +25,10 @@ const rootReducer = combineReducers({ org: orgReducer, event: eventReducer, project: projectReducer, + status: requestStatus, + proposal: proposalReducer, admin: adminReducers, comment: commentReducer, - status: requestStatus }); -export default rootReducer; \ No newline at end of file +export default rootReducer; diff --git a/src/reducers/notificationReducer.js b/src/reducers/notificationReducer.js index e6a2f32b..5942c936 100644 --- a/src/reducers/notificationReducer.js +++ b/src/reducers/notificationReducer.js @@ -1,26 +1,40 @@ -import { GET_PLATFORM_NOTIFICATIONS, GET_USER_NOTIFICATIONS } from "../actions/types" +import { + GET_PLATFORM_NOTIFICATIONS, + GET_USER_NOTIFICATIONS, + GET_PROPOSAL_NOTIFICATIONS, +} from "../actions/types"; const initialState = { platformNotifications: [], - userNotifications: [] -} + userNotifications: [], + proposalNotifications: [], +}; export default (state = initialState, action) => { - switch(action.type) { + switch (action.type) { case GET_PLATFORM_NOTIFICATIONS: { return { ...state, - platformNotifications: [action.payload, ...state.platformNotifications][0] - } + platformNotifications: [ + action.payload, + ...state.platformNotifications, + ][0], + }; } case GET_USER_NOTIFICATIONS: { return { ...state, - userNotifications: [action.payload, ...state.userNotifications][0] - } + userNotifications: [action.payload, ...state.userNotifications][0], + }; + } + case GET_PROPOSAL_NOTIFICATIONS: { + return { + ...state, + proposalNotifications: [action.payload, ...state.userNotifications][0], + }; } default: { - return state + return state; } } -} \ No newline at end of file +}; diff --git a/src/reducers/proposalReducer.js b/src/reducers/proposalReducer.js new file mode 100644 index 00000000..1f673384 --- /dev/null +++ b/src/reducers/proposalReducer.js @@ -0,0 +1,62 @@ +import { + CREATE_PROPOSAL, + GET_PROPOSAL, + EXIT, + GET_USER_PROPOSAL_NOTIFICATIONS, + GET_ALL_PROPOSALS, + GET_USER_PROPOSALS, +} from "../actions/types"; + +const initialState = { + createdProposal: {}, + fetchedProposal: {}, + proposalIsFetched: false, + userNotifications: [], + allProposals: [], + userProposals: [], +}; + +export default (state = initialState, action) => { + switch (action.type) { + case CREATE_PROPOSAL: { + return { + ...state, + createdProposal: action.payload, + }; + } + case GET_PROPOSAL: { + return { + ...state, + fetchedProposal: action.payload, + }; + } + case GET_USER_PROPOSAL_NOTIFICATIONS: { + return { + ...state, + userNotification: action.payload, + }; + } + case GET_ALL_PROPOSALS: { + return { + ...state, + allProposals: action.payload, + }; + } + case GET_USER_PROPOSALS: { + return { + ...state, + userProposals: action.payload, + }; + } + case EXIT: { + return { + ...state, + createdProposal: {}, + fetchedProposal: {}, + }; + } + default: { + return state; + } + } +}; diff --git a/src/router.js b/src/router.js index 92cdef44..a4d5b1cb 100644 --- a/src/router.js +++ b/src/router.js @@ -13,7 +13,6 @@ import PrivateRoute from "./common/PrivateRoute"; import Maintenance from "./maintenance/maintenance"; import Events from "./user/events/events"; import UserProposalDashboard from "./user/proposals/UserProposalDashboard/UserProposalDashboard"; -import AdminProposalDashboard from "./user/proposals/AdminProposalDashboard/AdminProposalDashboard"; import ProposalDiscussion from "./user/proposals/ProposalDiscussion/ProposalDiscussion"; import ProposalEditor from "./user/proposals/ProposalEditor/ProposalEditor"; import Admin from "./user/Admin/Admin"; @@ -38,19 +37,9 @@ const Router = () => ( - - diff --git a/src/user/dashboard/insights/components/memberInfo.scss b/src/user/dashboard/insights/components/memberInfo.scss index 847f1295..5065ef06 100644 --- a/src/user/dashboard/insights/components/memberInfo.scss +++ b/src/user/dashboard/insights/components/memberInfo.scss @@ -136,7 +136,7 @@ } } .list-group { - width: 14vw; + // width: 14vw; } .popover-body { width: 9vw; @@ -159,4 +159,4 @@ background: transparent; color: #EB5757; } -} +} \ No newline at end of file diff --git a/src/user/organization/organization.js b/src/user/organization/organization.js index 8d419c3a..5dd8c664 100644 --- a/src/user/organization/organization.js +++ b/src/user/organization/organization.js @@ -11,8 +11,10 @@ import topBarLoading from "../../placeholderLoading/topBarLoading/topBarLoading" import orgUpdatesLoading from "../../placeholderLoading/orgUpdatesLoading/orgUpdatesLoading"; import contactLoading from "../../placeholderLoading/contactLoading/contactLoading"; import cardLoading from "../../placeholderLoading/cardLoading/cardLoading"; -import { connect } from 'react-redux' -import { getOrgProfile } from '../../actions/orgAction' +import { connect } from "react-redux"; +import { getOrgProfile } from "../../actions/orgAction"; +import { Link } from "react-router-dom"; +import { Button } from "react-bootstrap"; class Organization extends Component { constructor(props) { @@ -20,31 +22,31 @@ class Organization extends Component { this.state = { org: true, isLoading: true, - orgProfile: {} + orgProfile: {}, }; } componentDidMount() { setTimeout(() => { - this.props.getOrgProfile() - }) + this.props.getOrgProfile(); + }); setTimeout(() => { this.setState({ isLoading: false }); }, 1000); } componentWillReceiveProps(nextProps) { - console.log('organization ', nextProps) - this.setState({ orgProfile: nextProps.org?.org }) + console.log("organization ", nextProps); + this.setState({ orgProfile: nextProps.org?.org }); } render() { - const { orgProfile } = this.state - const { - // name, - description, + const { orgProfile } = this.state; + const { + // name, + description, // contactInfo - } = orgProfile + } = orgProfile; return (
@@ -75,21 +77,36 @@ class Organization extends Component {
{orgProfile?.name}
Short description
-

{description?.shortDescription || "Short details of organization"}

+

+ {description?.shortDescription || + "Short details of organization"} +

About us in details
-

{description?.longDescription || "Long description of the organization"}

+

+ {description?.longDescription || + "Long description of the organization"} +

)}
+ + + {this.state.isLoading ? (
{orgUpdatesLoading()}
) : (
- {" "} - {" "} +
)} @@ -111,11 +128,11 @@ class Organization extends Component { ); } } -// map state to props +// map state to props const mapStateToProps = (state) => ({ auth: state.auth, error: state.error, - org: state.org -}) + org: state.org, +}); export default connect(mapStateToProps, { getOrgProfile })(Organization); diff --git a/src/user/organization/organization.scss b/src/user/organization/organization.scss index b4890be2..22b276cc 100644 --- a/src/user/organization/organization.scss +++ b/src/user/organization/organization.scss @@ -31,6 +31,7 @@ .org-info { display: flex; flex-direction: row; + padding-right: 10px; .posts { flex-grow: 2; h2 { @@ -84,6 +85,19 @@ flex: 1; flex-grow: 3; } + + .proposal-btn { + height: 50px; + width: 90%; + margin-left: 40px; + font-family: Inter; + font-style: normal; + font-weight: 600; + font-size: 16px; + line-height: 27px; + + color: #ffffff; + } } } .orgupdatesloading { diff --git a/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.js b/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.js deleted file mode 100644 index 9b1f0f51..00000000 --- a/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { Component } from "react"; -import "./AdminProposalDashboard.scss"; -import Navigation from "../../dashboard/navigation/navigation"; -import DashboardContent from "./DashboardContent/DashboardContent"; -import DashboardRightPanel from "./DashboardRightPanel/DashboardRightPanel"; - -class UserProposalDashboard extends Component { - constructor(props) { - super(props); - this.state = { - dashboard: true, - isLoading: true, - }; - } - render() { - return ( -
-
- -
-
- -
-
- -
-
- ); - } -} - -export default UserProposalDashboard; diff --git a/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.scss b/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.scss deleted file mode 100644 index 86e9c195..00000000 --- a/src/user/proposals/AdminProposalDashboard/AdminProposalDashboard.scss +++ /dev/null @@ -1,16 +0,0 @@ -.dashboard { - display: flex; - min-height: 100vh; - height: auto; - font-family: Muli, sans-serif; - .dashboard__navigation { - flex: 1; - border-right: solid 1px #dfe9f1; - } - .dashboard__content { - flex: 4; - } - .dashboard__rightpanel { - flex: 1.5; - } -} diff --git a/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.js b/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.js deleted file mode 100644 index 60f9dda1..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.js +++ /dev/null @@ -1,177 +0,0 @@ -import React, { Component } from "react"; -import { Button, Form, Image } from "react-bootstrap"; -import "./DashboardContent.scss"; -import userIcon2 from "../../../../images/userIcon2.jpg"; - -class DashboardContent extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
-
-
- - -
- Proposals -
-
-
-
- - - - - - - - -
-
-
-
- -
-
-
-
-
- icon -
-
-

Admin panel in donut dashboard

-

June 5, 2018 4:31 AM

-
- -
-
-
- ex sit ex laboris adipisicing enim eiusmod proident - exercitation ea fugiat in llit pariatur occaecat ut nostrud - ullamco ex official ex sit ex laboris adipisicing enim eiusmod - proident exercitation ea... -
-
- - -
-
-
-
-
-
- icon -
-
-

Admin panel in donut dashboard

-

June 5, 2018 4:31 AM

-
- -
-
-
- ex sit ex laboris adipisicing enim eiusmod proident - exercitation ea fugiat in llit pariatur occaecat ut nostrud - ullamco ex official ex sit ex laboris adipisicing enim eiusmod - proident exercitation ea... -
-
- - -
-
-
-
-
-
- icon -
-
-

Admin panel in donut dashboard

-

June 5, 2018 4:31 AM

-
- -
-
-
- ex sit ex laboris adipisicing enim eiusmod proident - exercitation ea fugiat in llit pariatur occaecat ut nostrud - ullamco ex official ex sit ex laboris adipisicing enim eiusmod - proident exercitation ea... -
-
- - -
-
-
-
-
-
- ); - } -} - -export default DashboardContent; diff --git a/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.scss b/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.scss deleted file mode 100644 index adc0732c..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardContent/DashboardContent.scss +++ /dev/null @@ -1,184 +0,0 @@ -.dashboard-content { - padding: 30px; - display: flex; - height: 100vh; - flex-direction: column; - - .searchbar-container { - flex-grow: 0.5; - .searchbar { - border-radius: 25px; - } - .dashboard-title { - margin-top: 15px; - .title-text { - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 36px; - line-height: 44px; - color: #000000; - } - } - .button-container { - .posts { - .category { - text-align: left; - margin-left: 0px; - margin-top: 20px; - .category-btn { - background-color: white; - font-family: Inter; - font-style: normal; - font-weight: 500; - font-size: 18px; - line-height: 22px; - - &:hover { - background-color: #1a73e8; - color: white; - } - - &:focus { - background-color: #1a73e8; - color: white; - } - } - } - } - } - } - .proposal-container { - margin-top: 20px; - flex-grow: 5; - .proposals { - .single-proposal { - display: inline-block; - counter-increment: item-counter; - width: 100%; - margin-bottom: 15px; - border: solid 1px #dfe9f1; - box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.1); - border-radius: 5px; - .user-info { - display: flex; - padding: 8px; - .image { - width: 38px; - height: 38px; - img { - width: 100%; - height: 100%; - border-radius: 2px; - } - } - .img-desc { - margin-left: 10px; - h2 { - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 18px; - line-height: 22px; - margin: 3px; - /* identical to box height */ - } - small { - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 12px; - line-height: 15px; - color: #90949c; - margin: 0; - } - .proposal-date { - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 12px; - line-height: 15px; - - color: #90949c; - } - } - .status-btn-draft { - background-color: white; - padding: 4px 36px; - border: solid 1px #eb5757; - border-radius: 100px; - color: #eb5757; - margin: 0 5px; - height: 30px; - cursor: default; - } - .status-btn-submitted { - background-color: white; - padding: 4px 36px; - border: solid 1px #90949c; - border-radius: 100px; - color: #90949c; - margin: 0 5px; - height: 30px; - cursor: default; - } - .status-btn-accepted { - background-color: white; - padding: 4px 36px; - border: solid 1px #27ae60; - border-radius: 100px; - color: #27ae60; - margin: 0 5px; - height: 30px; - cursor: default; - } - .dropdown-container { - margin-left: auto; - margin-right: 5px; - } - } - .proposal-content { - display: flex; - .proposal-details { - flex: 3; - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 14px; - line-height: 17px; - padding: 10px; - - color: #1d2129; - } - .proposal-options { - flex: 1.5; - text-align: center; - padding: 20px; - .option-btn { - background-color: white; - color: #007bff; - padding: 4px 40px; - border: solid 1px #1a73e8; - border-radius: 100px; - margin: 0 10px; - height: 30px; - cursor: pointer; - &.active { - background: #007bff; - color: white; - } - .option-text { - font-family: Inter; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 22px; - /* identical to box height */ - } - } - } - } - } - } - } -} diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.js b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.js deleted file mode 100644 index 3430f1aa..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.js +++ /dev/null @@ -1,72 +0,0 @@ -import React, { Component } from "react"; -import "./Comments.scss"; -import { ListGroup, Image } from "react-bootstrap"; -import userIcon2 from "../../../../../images/userIcon2.jpg"; - -class Comments extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
-
Comments
-
- - -
-
- icon -
-
-
Devesh
-
- "Lorem ipsum dolor sit amet" -
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna - aliqua. Ut enim ad minim veniam, quis nostrud exercitation -
-
-
-
-
- - -
-
- icon -
-
-
Devesh
-
- "Lorem ipsum dolor sit amet" -
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna - aliqua. Ut enim ad minim veniam, quis nostrud exercitation -
-
-
-
-
-
-
- ); - } -} - -export default Comments; diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.scss b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.scss deleted file mode 100644 index 88c79fca..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/Comments/Comments.scss +++ /dev/null @@ -1,69 +0,0 @@ -.comments { - .comment-title { - margin-top: 10px; - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 22px; - line-height: 27px; - - color: #000000; - } - .comments-container { - border: solid 1px #dfe9f1; - overflow: auto; - border-radius: 5px; - margin: 5px; - max-height: 300px; - .comment-item { - display: flex; - padding: none; - .image-container { - flex: 1; - .user-image { - width: 30px; - height: 30px; - } - } - .comment-container { - flex: 6; - border: solid 1px #dfe9f1; - overflow: auto; - border-radius: 5px; - padding: 3px; - .commenting-user { - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 14px; - line-height: 150%; - /* or 21px */ - - color: #000000; - } - .commented-section { - margin-top: 2px; - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 14px; - line-height: 150%; - /* or 21px */ - - color: rgba(29, 33, 41, 0.5); - } - .comment-text { - margin-top: 2px; - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 14px; - - /* or 21px */ - - color: rgba(21, 21, 21, 0.91); - } - } - } - } -} diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.js b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.js deleted file mode 100644 index 106355b4..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.js +++ /dev/null @@ -1,25 +0,0 @@ -import React, { Component } from "react"; -import "./DashboardRightPanel.scss"; -import Comments from "./Comments/Comments"; -import OtherIdeas from "./OtherIdeas/OtherIdeas"; - -class DashboardRightPanel extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
-
- -
-
- -
-
- ); - } -} - -export default DashboardRightPanel; diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss deleted file mode 100644 index 133ebce0..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss +++ /dev/null @@ -1,12 +0,0 @@ -.panel { - display: flex; - flex-direction: column; - - .panel-comments { - flex-grow: 1; - } - .panel-ideas { - margin-top: 10px; - flex-grow: 1; - } -} diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js deleted file mode 100644 index a64b31b3..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js +++ /dev/null @@ -1,119 +0,0 @@ -import React, { Component } from "react"; -import "./OtherIdeas.scss"; -import { ListGroup, Image } from "react-bootstrap"; -import userIcon2 from "../../../../../images/userIcon2.jpg"; - -class OtherIdeas extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
-
Other Ideas
-
- - -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
-
-
-
- ); - } -} - -export default OtherIdeas; diff --git a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss b/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss deleted file mode 100644 index 6058404f..00000000 --- a/src/user/proposals/AdminProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss +++ /dev/null @@ -1,52 +0,0 @@ -.ideas { - .ideas-title { - margin-top: 10px; - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 22px; - line-height: 27px; - - color: #000000; - } - .ideas-container { - border: solid 1px #dfe9f1; - overflow: auto; - border-radius: 5px; - margin: 5px; - max-height: 300px; - .idea-item { - display: flex; - padding: none; - .image-container { - flex: 1; - .user-image { - width: 30px; - height: 30px; - } - } - .idea-container { - flex: 6; - .idea-title { - font-family: Inter; - font-style: normal; - font-weight: 600; - font-size: 14px; - line-height: 21px; - /* identical to box height, or 150% */ - - color: #000000; - } - .idea-description { - font-family: Inter; - font-style: normal; - font-weight: normal; - font-size: 12px; - line-height: 15px; - - color: rgba(29, 33, 41, 0.5); - } - } - } - } -} diff --git a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.js b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.js index df121134..81c02670 100644 --- a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.js +++ b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.js @@ -1,14 +1,47 @@ import React, { Component } from "react"; -// import userIcon2 from "../../../../../images/userIcon2.jpg"; -import { Form, ListGroup } from "react-bootstrap"; +import { Form, ListGroup, Button } from "react-bootstrap"; import "./DiscussionComments.scss"; +import Carousel, { Modal, ModalGateway } from "react-images"; +import { connect } from "react-redux"; +import { commentProposal } from "../../../../../actions/proposalActions"; class DiscussionComments extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + commentContent: "", + commentItems: this.props.commentItems, + imageModalOpen: false, + }; } + handleComment = (text) => { + const { userId, proposalId, isAuthor, author } = this.props; + + const commentData = { + userId: userId, + proposalId: proposalId, + comment: this.state.commentContent, + isAuthor: isAuthor, + author: author, + }; + this.props.commentProposal(commentData); + this.props.handleComment(this.state.commentContent); + this.setState({ + commentContent: "", + }); + }; + + handleTextCHange = (e) => { + this.setState({ + commentContent: e.target.value, + }); + }; + + toggleModal = () => { + this.setState((state) => ({ imageModalOpen: !state.imageModalOpen })); + }; + render() { const comments = this.props.commentItems; return ( @@ -20,19 +53,52 @@ class DiscussionComments extends Component {
-
+ +
+
+
Attached Images
+
+ {this.props.images.map((item, index) => { + return ( +
+ +
+ ); + })} +
+ + + {this.state.imageModalOpen ? ( + + + + ) : null} + +
); } } -export default DiscussionComments; +export default connect(null, { commentProposal })(DiscussionComments); diff --git a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.scss b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.scss index 881d97d1..64ce7a5d 100644 --- a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.scss +++ b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionComments/DiscussionComments.scss @@ -1,13 +1,16 @@ .commentbox { + display: flex; + flex-direction: column; + .comments { + flex: 2; .comment-title { - margin-top: 10px; font-family: Inter; font-style: normal; font-weight: 600; font-size: 22px; line-height: 27px; - + margin-top: 0px; color: #000000; } .comments-containers { @@ -15,7 +18,7 @@ overflow: auto; border-radius: 5px; margin: 5px 5px -1px 5px; - max-height: 73vh; + height: 300px; .comment-item { display: flex; @@ -79,6 +82,52 @@ .textinput { border-radius: 25px; } + + .textinput-container { + .form-text { + display: inline-block; + margin-right: 10px; + width: 70%; + } + .form-button { + width: 25%; + } + } + } + } + .images { + flex: 1; + + .images-title { + font-family: Inter; + font-style: normal; + font-weight: 600; + font-size: 22px; + line-height: 27px; + margin-top: 0px; + color: #000000; + } + .gallery { + overflow: hidden; + margin-left: 2; + margin-right: 2; + padding: 12px; + border: 1px solid #dfe9f1; + height: 100%; + .gallery-item { + box-sizing: border-box; + float: left; + margin: 2px; + margin-right: 10px; + overflow: hidden; + padding-bottom: 16%; + position: relative; + width: calc(25% - 4px); + .image-item { + max-width: 100%; + position: absolute; + } + } } } } diff --git a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.js b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.js index f9df6d1b..7463f400 100644 --- a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.js +++ b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.js @@ -1,24 +1,91 @@ import React, { Component } from "react"; import "./DiscussionContent.scss"; -import { Button, Row, Image, ListGroup } from "react-bootstrap"; +import { Button, Badge, Image, ListGroup } from "react-bootstrap"; import DiscussionComments from "./DiscussionComments/DiscussionComments"; -import eventImg from "../../../../svgs/event-img-1.svg"; import userIcon2 from "../../../../images/userIcon2.jpg"; import RequestChanges from "../DiscussionPopups/RequestChanges"; +import { withRouter, Link } from "react-router-dom"; +import { Editor } from "@tinymce/tinymce-react"; +import { connect } from "react-redux"; +import { getProposal } from "../../../../actions/proposalActions"; class DiscussionContent extends Component { constructor(props) { super(props); - this.state = { comments: [], showModal: false, selectedText: "" }; + this.state = { + comments: [], + showModal: false, + selectedText: "", + proposalId: "", + isAdmin: false, + proposalTitle: "", + markdownString: "", + proposalDescription: "", + commentList: [], + author: "", + images: [{ source: "../../../../images/userIcon2.jpg" }], + imageModalOpen: false, + proposalState: "", + variant: "danger", + }; } + //Token would be passed down from the componentDidMount() { - this.processComments(); + const { proposalId, isAdmin, userId, token } = this.props.location.state; + + this.setState( + { + proposalId: proposalId, + isAdmin: isAdmin, + userId: userId, + token: token, + }, + () => { + this.props.getProposal(this.state.proposalId); + } + ); } + + componentWillReceiveProps(nextProps) { + const { fetchedProposal } = nextProps; + const images = []; + let variant = ""; + + fetchedProposal.attachments.forEach((item, index) => { + images.push({ source: item.fileLink }); + }); + + switch (fetchedProposal.proposalStatus) { + case "DRAFT": + variant = "danger"; + break; + case "SUBMITTED": + variant = "secondary"; + break; + } + + this.setState( + { + proposalTitle: fetchedProposal.title, + markdownString: fetchedProposal.content, + proposalDescription: fetchedProposal.proposalDescription, + commentList: fetchedProposal.comments, + author: fetchedProposal.creator, + proposalState: fetchedProposal.proposalStatus, + + images: images, + }, + () => { + this.processComments(); + } + ); + } + processComments = () => { let comments = []; - for (let i = 0; i < 6; i++) { + this.state.commentList.forEach((commentItem) => { comments.push(
@@ -31,26 +98,24 @@ class DiscussionContent extends Component { />
-
Devesh
-
- "Lorem ipsum dolor sit amet" -
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do - eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut - enim ad minim veniam, quis nostrud exercitation -
+
{commentItem.userName}
+
{commentItem.comment}
); - } + }); this.setState({ comments: comments, }); }; + toggleModal = () => { + this.setState((state) => ({ imageModalOpen: !state.imageModalOpen })); + }; + handleTextSelction = () => { + console.log("text selection called"); if (window.getSelection().toString().length > 0) { this.setState( { @@ -96,104 +161,74 @@ class DiscussionContent extends Component { }; render() { + const { imageModalOpen, images } = this.state; return (
- Proposal Title Here + + {this.state.proposalTitle}{" "} +
+ + {this.state.proposalState} + +
+
+
- + + +
-

- Fugiat esse aliquip sint culpa. Nulla amet ipsum non commodo - veniam velit officia dolor laborum et aliquip ad velit veniam. - Consequat mollit consequat adipisicing duis consectetur duis non - fugiat et in elit consectetur sint. Mollit id aliqua commodo - duis sint non. Officia sunt consectetur et officia officia ad - officia aliquip qui enim aliquip officia minim. Minim consequat - duis deserunt aliqua qui consectetur tempor ex aliquip occaecat - ad veniam consectetur. Dolor et laboris sit esse laborum ex - deserunt nisi magna eiusmod. Mollit non ipsum laboris nulla - commodo enim elit magna amet. Quis officia incididunt aute elit - veniam ullamco ea elit reprehenderit. Pariatur exercitation ut - quis occaecat esse consectetur eu eiusmod ut et exercitation. - Nisi pariatur eu deserunt aliqua cillum dolore. Dolore duis - laboris occaecat incididunt minim aliqua. -

-

- Heading Irure mollit mollit proident amet sunt ea deserunt do - anim proident mollit. Aliquip fugiat quis ipsum est nisi ut - magna excepteur aliquip reprehenderit occaecat. Ea enim officia - labore consectetur et ad. Mollit ut duis nulla amet dolor minim - laborum amet cillum velit. Incididunt elit quis ipsum velit esse - eu adipisicing sint voluptate ea ipsum. Ullamco pariatur - incididunt tempor qui voluptate id deserunt tempor. Consectetur - mollit aute consequat ut non amet fugiat eiusmod. Cupidatat - velit ea eu veniam proident irure ullamco dolor aliquip nisi - minim. Nisi consequat sit ea anim duis in id mollit ipsum aute - mollit commodo excepteur occaecat. Aliqua magna sunt in et duis - veniam. Cillum in sunt sint officia. Dolor aliqua irure dolor - adipisicing et culpa. Heading Cupidatat pariatur exercitation - enim adipisicing qui labore officia cupidatat. Proident amet - minim cupidatat proident velit in ea sint velit. Duis - adipisicing excepteur cupidatat consequat ex non cupidatat ea - non. Commodo ad anim. Cupidatat pariatur exercitation enim - adipisicing qui labore officia cupidatat. Proident amet minim - cupidatat proident velit in ea sint velit. Duis adipisicing - excepteur cupidatat consequat ex non cupidatat ea non. Commodo - ad anim.Cupidatat pariatur exercitation enim adipisicing qui - labore officia cupidatat. Proident amet minim cupidatat proident - velit in ea sint velit. Duis adipisicing excepteur cupidatat - consequat ex non cupidatat ea non. Commodo ad anim. -

-

- Heading Irure mollit mollit proident amet sunt ea deserunt do - anim proident mollit. Aliquip fugiat quis ipsum est nisi ut - magna excepteur aliquip reprehenderit occaecat. Ea enim officia - labore consectetur et ad. Mollit ut duis nulla amet dolor minim - laborum amet cillum velit. Incididunt elit quis ipsum velit esse - eu adipisicing sint voluptate ea ipsum. Ullamco pariatur - incididunt tempor qui voluptate id deserunt tempor. Consectetur - mollit aute consequat ut non amet fugiat eiusmod. Cupidatat - velit ea eu veniam proident irure ullamco dolor aliquip nisi - minim. Nisi consequat sit ea anim duis in id mollit ipsum aute - mollit commodo excepteur occaecat. Aliqua magna sunt in et duis - veniam. Cillum in sunt sint officia. Dolor aliqua irure dolor - adipisicing et culpa. Heading Cupidatat pariatur exercitation - enim adipisicing qui labore officia cupidatat. Proident amet - minim cupidatat proident velit in ea sint velit. Duis - adipisicing excepteur cupidatat consequat ex non cupidatat ea - non. Commodo ad anim. Cupidatat pariatur exercitation enim - adipisicing qui labore officia cupidatat. Proident amet minim - cupidatat proident velit in ea sint velit. Duis adipisicing - excepteur cupidatat consequat ex non cupidatat ea non. Commodo - ad anim.Cupidatat pariatur exercitation enim adipisicing qui - labore officia cupidatat. Proident amet minim cupidatat proident - velit in ea sint velit. Duis adipisicing excepteur cupidatat - consequat ex non cupidatat ea non. Commodo ad anim. -

-
-
-
Attached Images
- - - - +
- +
{ this.handleClose(); }} @@ -206,4 +241,10 @@ class DiscussionContent extends Component { } } -export default DiscussionContent; +const mapStateToProps = (state) => ({ + fetchedProposal: state.proposal.fetchedProposal, +}); + +export default connect(mapStateToProps, { getProposal })( + withRouter(DiscussionContent) +); diff --git a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.scss b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.scss index 6ac75b44..265b8816 100644 --- a/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.scss +++ b/src/user/proposals/ProposalDiscussion/DiscussionContent/DiscussionContent.scss @@ -4,12 +4,12 @@ height: 100vh; flex-direction: column; .discussion-toppanel { - flex-grow: 1; + flex: 0.5; + display: flex; flex-direction: row; .discussion-title { flex-grow: 5; - .title-text { font-family: Inter; font-style: normal; @@ -48,19 +48,17 @@ } } .discussion-bottompanel { - flex-grow: 4; + flex: 4; display: flex; .proposal-preview { - margin-top: 20px; flex: 2; display: flex; flex-direction: column; - max-height: 80vh; + max-height: 85vh; .proposal-text { - overflow: auto; - flex-grow: 4; + flex: 4; font-family: Inter; font-style: normal; font-weight: normal; @@ -70,8 +68,8 @@ color: #1d2129; } .attached-images { - padding: 10px 10px 0px 0px; - flex-grow: 1; + padding: 0px 10px 0px 0px; + flex: 1; .images-title { margin-top: 10px; font-family: Inter; @@ -83,7 +81,7 @@ color: #000000; } .image-item { - max-height: 10em; + max-height: 8em; margin-right: 10px; margin-left: 10px; } diff --git a/src/user/proposals/ProposalEditor/EditorContent/DropZone.js b/src/user/proposals/ProposalEditor/EditorContent/DropZone.js new file mode 100644 index 00000000..6ede4ec0 --- /dev/null +++ b/src/user/proposals/ProposalEditor/EditorContent/DropZone.js @@ -0,0 +1,96 @@ +import React, { useMemo, useCallback, useState } from "react"; +import { useDropzone } from "react-dropzone"; +import { toast, ToastContainer } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; + +const baseStyle = { + flex: 1, + display: "flex", + flexDirection: "column", + alignItems: "center", + padding: "20px", + borderWidth: 2, + borderRadius: 2, + borderColor: "#eeeeee", + borderStyle: "dashed", + backgroundColor: "#fafafa", + color: "#bdbdbd", + outline: "none", + transition: "border .24s ease-in-out", + height: "160px", +}; + +const activeStyle = { + borderColor: "#2196f3", +}; + +const acceptStyle = { + borderColor: "#00e676", +}; + +const rejectStyle = { + borderColor: "#ff1744", +}; + +function StyledDropzone(props) { + const [proposalId, setProposalId] = useState(props.idContent); + + const onDrop = useCallback((acceptedFiles) => { + if (proposalId === "new") { + toast.error( + "Please save the proposal as a draft before attaching images" + ); + } else { + let formData = new FormData(); + formData.append("file", acceptedFiles[0]); + const URL = `http://localhost:5000/proposal/attach/${props.idContent}`; + + fetch(URL, { + method: "POST", + body: formData, + headers: { + Authorization: localStorage.getItem("jwtToken"), + }, + }) + .then((res) => { + toast.success("Image successfully attached to proposal!"); + }) + .catch((err) => { + console.log(err); + }); + } + }, []); + + const { + getRootProps, + getInputProps, + isDragActive, + isDragAccept, + isDragReject, + } = useDropzone({ onDrop, accept: "image/*" }); + + const style = useMemo( + () => ({ + ...baseStyle, + ...(isDragActive ? activeStyle : {}), + ...(isDragAccept ? acceptStyle : {}), + ...(isDragReject ? rejectStyle : {}), + }), + [isDragActive, isDragReject, isDragAccept] + ); + + return ( +
+
+ +

+ Drag 'n' drop some images here, or click to select an image. Files + dropped here would be attached to the proposal. +

+
+ +
+ ); +} + +export default StyledDropzone; diff --git a/src/user/proposals/ProposalEditor/EditorContent/EditorContent.js b/src/user/proposals/ProposalEditor/EditorContent/EditorContent.js index 4c04a860..64521ec0 100644 --- a/src/user/proposals/ProposalEditor/EditorContent/EditorContent.js +++ b/src/user/proposals/ProposalEditor/EditorContent/EditorContent.js @@ -1,12 +1,398 @@ import React, { Component } from "react"; +import { Button, Form, Badge } from "react-bootstrap"; +import "./EditorContent.scss"; +import { withRouter } from "react-router-dom"; +import { BeatLoader } from "react-spinners"; +import { toast, ToastContainer } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; +import StyledDropzone from "./DropZone"; +import { Link } from "react-router-dom"; +import { Editor } from "@tinymce/tinymce-react"; +import { connect } from "react-redux"; +import { + createProposal, + getProposal, + saveProposal, + submitProposal, + deleteProposal, +} from "../../../../actions/proposalActions"; + +//Separately importing styles related to the markdown editor +import "./index.css"; + class EditorContent extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + currentText: "", + lastText: "", + newProposal: false, + proposalTitle: "", + proposalId: "", + proposalStatus: "DRAFT", + markdownString: "", + proposalDescription: "", + startSave: false, + isSaving: false, + lastSaved: new Date().toTimeString().substring(0, 8), + }; + } + + componentWillReceiveProps(nextProps) { + const { fetchedProposal, createdProposal } = nextProps; + + if (Object.keys(fetchedProposal).length !== 0) { + this.setState({ + proposalTitle: fetchedProposal.title, + proposalDescription: fetchedProposal.proposalDescription, + markdownString: fetchedProposal.content, + proposalId: fetchedProposal._id, + proposalStatus: fetchedProposal.proposalStatus, + }); + } + if (Object.keys(createProposal).length !== 0) { + this.setState( + { + isSaving: false, + newProposal: false, + proposalId: createdProposal._id, + lastSaved: new Date().toTimeString().substring(0, 8), + }, + () => { + let idVar = setInterval(this.saveProposal, 20000); + this.setState({ + idVar: idVar, + startSave: true, + }); + } + ); + } + } + + componentDidMount() { + //This means proposal is previosuly saved + if (this.props.location.state.proposalId !== "new") { + let idVar = setInterval(this.saveProposal, 20000); + this.setState( + { + idVar: idVar, + proposalId: this.props.location.state.proposalId, + startSave: true, + }, + () => { + setTimeout(() => { + this.props.getProposal(this.props.location.state.proposalId); + }); + } + ); + } + //New proposal + else { + this.setState({ + newProposal: true, + }); + } + } + + //Update the content of the proposal + saveProposal = () => { + let { lastText, currentText } = this.state; + + if (lastText !== currentText) { + this.setState({ isSaving: true }); + let proposalInfo = { + title: this.state.proposalTitle, + description: this.state.proposalDescription, + content: this.state.currentText, + proposalId: this.state.proposalId, + }; + + setTimeout(() => { + this.props.saveProposal(proposalInfo); + this.setState({ + isSaving: false, + }); + }, 2000); + } + }; + + createProposal = () => { + this.setState({ isSaving: true }); + setTimeout(() => { + let proposalInfo = { + title: this.state.proposalTitle, + content: this.state.currentText, + proposalStatus: "DRAFT", + creator: localStorage.getItem("userId"), + proposalDescription: this.state.proposalDescription, + }; + + this.props.createProposal(proposalInfo); + + let idVar = setInterval(this.saveProposal, 20000); + this.setState({ + idVar: idVar, + startSave: true, + newProposal: false, + }); + }, 2000); + }; + + submitProposal = () => { + const proposalData = { + proposalId: this.state.proposalId, + proposalStatus: "SUBMITTED", + }; + this.props.submitProposal(proposalData); + setTimeout(() => { + this.props.history.push("/proposal"); + }, 3000); + toast.success("Proposal Successfully Submitted! Redirecting to dashboard"); + }; + + handleEditorChange = ({ html, text }) => { + this.setState({ + draftEnabled: true, + currentText: html, + }); + }; + + handleDraftClick = () => { + if (this.state.newProposal) { + this.createProposal(); + } + }; + + onSubmitHandler = () => { + this.submitProposal(); + }; + + handleChange = (evt) => { + const value = evt.target.value; + + this.setState({ + ...this.state, + [evt.target.name]: value, + }); + }; + + handleDeleteProposal = () => { + this.props.deleteProposal(this.state.proposalId); + setTimeout(() => { + this.props.history.push("/proposal"); + }, 3000); + toast.error("Proposal Deleted Successfully. Redirecting to dashboard"); + }; + + componentWillUnmount() { + clearInterval(this.state.idVar); } + + handleTinyEditorChange = (content, editor) => { + this.setState({ + draftEnabled: true, + currentText: content, + }); + }; + render() { - return
; + return ( +
+
+
+ Write your Proposal +
+
+ Proposal Title + + Short Description + + +
+
+
+ {this.state.newProposal ? ( + + ) : ( + + + + + + + )} + {this.state.proposalStatus === "DRAFT" ? ( + + ) : null} + +
+ {!this.state.newProposal ? ( + + ) : ( +
+ )} +
+
+
+
+ +
+ {this.state.startSave ? ( +
+ {this.state.isSaving ? ( +
+
+ +
+
+ Saving +
+
+ ) : ( +
+ Last saved at {this.state.lastSaved} +
+ )} +
+ ) : ( + + )} + +
+ ); } } -export default EditorContent; +const mapStateToProps = (state) => ({ + createdProposal: state.proposal.createdProposal, + fetchedProposal: state.proposal.fetchedProposal, + proposalIsFetched: state.proposal.proposalIsFetched, +}); + +export default connect(mapStateToProps, { + createProposal, + getProposal, + saveProposal, + submitProposal, + deleteProposal, +})(withRouter(EditorContent)); diff --git a/src/user/proposals/ProposalEditor/EditorContent/EditorContent.scss b/src/user/proposals/ProposalEditor/EditorContent/EditorContent.scss index e69de29b..345cd335 100644 --- a/src/user/proposals/ProposalEditor/EditorContent/EditorContent.scss +++ b/src/user/proposals/ProposalEditor/EditorContent/EditorContent.scss @@ -0,0 +1,88 @@ +.editor-content { + padding: 30px; + display: flex; + height: 100vh; + flex-direction: column; + .editor-toppanel { + flex-grow: 1; + display: flex; + flex-direction: row; + .editor-title { + flex-grow: 5; + width: 60%; + .form-container { + margin-top: 10px; + } + .title-text { + font-family: Inter; + font-style: normal; + font-weight: 600; + font-size: 36px; + line-height: 44px; + + color: #1d2129; + } + } + .editor-buttons { + flex-grow: 1; + text-align: right; + .option-btn { + background: #fff; + border-radius: 100px; + padding: 4px 20px; + color: #007bff; + margin: 0 10px; + height: 40px; + max-width: 170px; + cursor: pointer; + &:active { + background: #fff; + color: #007bff; + } + &:hover { + background: #fff; + color: #007bff; + } + .option-text { + font-family: Inter; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 19px; + /* identical to box height */ + } + } + } + } + .proposal-bottompanel { + flex-grow: 5; + display: flex; + } + + .last-saved { + margin: 10px; + font-family: Inter; + font-size: 12px; + font-weight: 400; + display: inline-block; + } + + .save-container { + display: flex; + flex-direction: row; + .container-outer { + order: 4; + .save-spinner { + display: inline-block; + margin: 10px 10px 10px 0px; + } + .save-text { + margin: 10px; + font-family: Inter; + font-size: 10px; + font-weight: 400; + display: inline inline-block; + } + } + } +} diff --git a/src/user/proposals/ProposalEditor/EditorContent/index.css b/src/user/proposals/ProposalEditor/EditorContent/index.css new file mode 100644 index 00000000..de804d4f --- /dev/null +++ b/src/user/proposals/ProposalEditor/EditorContent/index.css @@ -0,0 +1,470 @@ +@font-face { + font-family: rmel-iconfont; + src: url(data:application/vnd.ms-fontobject;base64,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); + src: url(data:font/ttf;base64,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) + format("truetype"); +} +.rmel-iconfont { + font-family: rmel-iconfont !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.rmel-icon-keyboard:before { + content: "\ed80"; +} +.rmel-icon-delete:before { + content: "\ed3c"; +} +.rmel-icon-code-block:before { + content: "\e941"; +} +.rmel-icon-code:before { + content: "\ed3b"; +} +.rmel-icon-visibility:before { + content: "\ed44"; +} +.rmel-icon-view-split:before { + content: "\ed45"; +} +.rmel-icon-link:before { + content: "\ed5f"; +} +.rmel-icon-redo:before { + content: "\ed60"; +} +.rmel-icon-undo:before { + content: "\ed61"; +} +.rmel-icon-bold:before { + content: "\ed6f"; +} +.rmel-icon-italic:before { + content: "\ed70"; +} +.rmel-icon-list-ordered:before { + content: "\ed71"; +} +.rmel-icon-list-unordered:before { + content: "\ed72"; +} +.rmel-icon-quote:before { + content: "\ed73"; +} +.rmel-icon-strikethrough:before { + content: "\ed74"; +} +.rmel-icon-underline:before { + content: "\ed75"; +} +.rmel-icon-wrap:before { + content: "\ed77"; +} +.rmel-icon-font-size:before { + content: "\ed78"; +} +.rmel-icon-grid:before { + content: "\ed8c"; +} +.rmel-icon-image:before { + content: "\ed8d"; +} +.rmel-icon-expand-less:before { + content: "\ed9f"; +} +.rmel-icon-expand-more:before { + content: "\eda0"; +} +.rmel-icon-fullscreen-exit:before { + content: "\eda1"; +} +.rmel-icon-fullscreen:before { + content: "\eda2"; +} +.rc-md-navigation { + min-height: 38px; + padding: 0 8px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border-bottom: 1px solid #e0e0e0; + font-size: 16px; + background: #f5f5f5; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; +} +.rc-md-navigation.in-visible { + display: none; +} +.rc-md-navigation .navigation-nav { + -webkit-box-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + justify-content: center; + font-size: 14px; + color: #757575; +} +.rc-md-navigation .button-wrap, +.rc-md-navigation .navigation-nav { + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + flex-direction: row; +} +.rc-md-navigation .button-wrap { + -webkit-flex-wrap: wrap; + flex-wrap: wrap; +} +.rc-md-navigation .button-wrap .button { + min-width: 24px; + height: 40px; + margin-right: 5px; + display: inline-block; + cursor: pointer; + line-height: 28px; + text-align: center; + color: #757575; +} +.rc-md-navigation .button-wrap .button:hover { + color: #212121; +} +.rc-md-navigation .button-wrap .button.disabled { + color: #bdbdbd; + cursor: not-allowed; +} +.rc-md-navigation .button-wrap .rmel-iconfont { + font-size: 18px; +} +.rc-md-navigation li, +.rc-md-navigation ul { + list-style: none; + margin: 0; + padding: 0; +} +.rc-md-navigation .h1, +.rc-md-navigation .h2, +.rc-md-navigation .h3, +.rc-md-navigation .h4, +.rc-md-navigation .h5, +.rc-md-navigation .h6, +.rc-md-navigation h1, +.rc-md-navigation h2, +.rc-md-navigation h3, +.rc-md-navigation h4, +.rc-md-navigation h5, +.rc-md-navigation h6 { + font-family: inherit; + font-weight: 500; + color: inherit; + padding: 0; + margin: 0; + line-height: 1.1; +} +.rc-md-navigation h1 { + font-size: 34px; +} +.rc-md-navigation h2 { + font-size: 30px; +} +.rc-md-navigation h3 { + font-size: 24px; +} +.rc-md-navigation h4 { + font-size: 18px; +} +.rc-md-navigation h5 { + font-size: 14px; +} +.rc-md-navigation h6 { + font-size: 12px; +} +.rc-md-editor .tool-bar { + position: absolute; + z-index: 1; + right: 8px; + top: 8px; +} +.rc-md-editor .tool-bar .button { + min-width: 24px; + height: 28px; + margin-right: 5px; + display: inline-block; + cursor: pointer; + font-size: 14px; + line-height: 28px; + text-align: center; + color: #999; +} +.rc-md-editor .tool-bar .button:hover { + color: #333; +} +.rc-md-editor { + height: 100%; + min-height: 0; + padding-bottom: 1px; + position: relative; + border: 1px solid #e0e0e0; + background: #fff; + -webkit-box-sizing: border-box; + box-sizing: border-box; + display: -webkit-box; + display: -webkit-flex; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + flex-direction: column; +} +.rc-md-editor.full { + width: 100%; + height: 100% !important; + position: fixed; + left: 0; + top: 0; + z-index: 1000; +} +.rc-md-editor .editor-container { + -webkit-box-flex: 1; + -webkit-flex: 1; + flex: 1; + display: -webkit-box; + display: -webkit-flex; + display: flex; + width: 100%; + min-height: 0; + position: relative; +} +.rc-md-editor .editor-container > .section.in-visible { + display: none; +} +.rc-md-editor .editor-container > .section > .section-container { + padding: 15px; + padding-top: 10px; +} +.rc-md-editor .editor-container .sec-md { + -webkit-box-flex: 1; + -webkit-flex: 1; + flex: 1; + min-height: 0; + min-width: 0; +} +.rc-md-editor .editor-container .sec-md .input { + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 100%; + overflow-y: scroll; + border: none; + resize: none; + outline: none; + min-height: 0; + background: #fff; + color: #333; + font-size: 14px; + line-height: 1.7; +} +.rc-md-editor .editor-container .sec-html { + -webkit-box-flex: 1; + -webkit-flex: 1; + flex: 1; + min-height: 0; + min-width: 0; +} +.rc-md-editor .editor-container .sec-html .html-wrap { + height: 100%; + -webkit-box-sizing: border-box; + box-sizing: border-box; + overflow: auto; +} +.custom-html-style { + color: #333; +} +.custom-html-style h1 { + font-size: 32px; + padding: 0; + border: none; + font-weight: 700; + margin: 32px 0; + line-height: 1.2; +} +.custom-html-style h2 { + font-size: 24px; + padding: 0 0; + border: none; + font-weight: 700; + margin: 24px 0; + line-height: 1.7; +} +.custom-html-style h3 { + font-size: 18px; + margin: 18px 0; + padding: 0 0; + line-height: 1.7; + border: none; +} +.custom-html-style p { + font-size: 14px; + line-height: 1.7; + margin: 8px 0; +} +.custom-html-style a { + color: #0052d9; +} +.custom-html-style a:hover { + text-decoration: none; +} +.custom-html-style strong { + font-weight: 700; +} +.custom-html-style ol, +.custom-html-style ul { + font-size: 14px; + line-height: 28px; + padding-left: 36px; +} +.custom-html-style li { + margin-bottom: 8px; + line-height: 1.7; +} +.custom-html-style hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.custom-html-style pre { + display: block; + padding: 20px; + line-height: 28px; + word-break: break-word; +} +.custom-html-style code, +.custom-html-style pre { + background-color: #f5f5f5; + font-size: 14px; + border-radius: 0; + overflow-x: auto; +} +.custom-html-style code { + padding: 3px 0; + margin: 0; + word-break: normal; +} +.custom-html-style code:after, +.custom-html-style code:before { + letter-spacing: 0; +} +.custom-html-style blockquote { + position: relative; + margin: 16px 0; + padding: 5px 8px 5px 30px; + background: none repeat scroll 0 0 rgba(102, 128, 153, 0.05); + border: none; + color: #333; + border-left: 10px solid #d6dbdf; +} +.custom-html-style img, +.custom-html-style video { + max-width: 100%; +} +.custom-html-style table { + font-size: 14px; + line-height: 1.7; + max-width: 100%; + overflow: auto; + border: 1px solid #f6f6f6; + border-collapse: collapse; + border-spacing: 0; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.custom-html-style table td, +.custom-html-style table th { + word-break: break-all; + word-wrap: break-word; + white-space: normal; +} +.custom-html-style table tr { + border: 1px solid #efefef; +} +.custom-html-style table tr:nth-child(2n) { + background-color: transparent; +} +.custom-html-style table th { + text-align: center; + font-weight: 700; + border: 1px solid #efefef; + padding: 10px 6px; + background-color: #f5f7fa; + word-break: break-word; +} +.custom-html-style table td { + border: 1px solid #efefef; + text-align: left; + padding: 10px 15px; + word-break: break-word; + min-width: 60px; +} +.rc-md-editor .drop-wrap { + display: block; + position: absolute; + left: 0; + top: 28px; + z-index: 2; + min-width: 20px; + padding: 10px 0; + text-align: center; + background-color: #fff; + border: 1px solid #f1f1f1; + border-right-color: #ddd; + border-bottom-color: #ddd; +} +.rc-md-editor .drop-wrap.hidden { + display: none !important; +} +.rc-md-editor .header-list .list-item { + width: 100px; + -webkit-box-sizing: border-box; + box-sizing: border-box; + padding: 8px 0; +} +.rc-md-editor .header-list .list-item:hover { + background: #f5f5f5; +} +.rc-md-editor .table-list.wrap { + position: relative; + margin: 0 10px; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} +.rc-md-editor .table-list.wrap .list-item { + position: absolute; + top: 0; + left: 0; + display: inline-block; + width: 20px; + height: 20px; + background-color: #e0e0e0; + border-radius: 3px; +} +.rc-md-editor .table-list.wrap .list-item.active { + background: #9e9e9e; +} diff --git a/src/user/proposals/ProposalEditor/ProposalEditor.js b/src/user/proposals/ProposalEditor/ProposalEditor.js index 04378eaf..abf80e7d 100644 --- a/src/user/proposals/ProposalEditor/ProposalEditor.js +++ b/src/user/proposals/ProposalEditor/ProposalEditor.js @@ -1,6 +1,7 @@ import React, { Component } from "react"; import Navigation from "../../dashboard/navigation/navigation"; import EditorContent from "./EditorContent/EditorContent"; +import "./ProposalEditor.scss"; class ProposalEditor extends Component { constructor(props) { diff --git a/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.js b/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.js index 032cc2b2..e76c1073 100644 --- a/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.js +++ b/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.js @@ -2,12 +2,117 @@ import React, { Component } from "react"; import { Button, Form, Image } from "react-bootstrap"; import "./DashboardContent.scss"; import userIcon2 from "../../../../images/userIcon2.jpg"; +import { Link } from "react-router-dom"; +import { connect } from "react-redux"; +import { + getProposalsByUser, + getAllProposals, +} from "../../../../actions/proposalActions"; class DashboardContent extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + userId: localStorage.getItem("userId"), + proposals: [], + displayItems: [], + allProposals: [], + userProposals: [], + }; } + + componentDidMount() { + this.props.getAllProposals(); + this.props.getProposalsByUser(this.state.userId); + } + + componentWillReceiveProps(nextProps) { + const { allProposals, userProposals } = nextProps; + + this.setState({ + allProposals: allProposals, + userProposals: userProposals, + displayItems: allProposals, + }); + } + + handleSearchBarChange = (evt) => { + const value = evt.target.value.toLowerCase(); + const proposals = this.state.proposals; + let results = []; + + if (value.length === 0) { + this.setState({ + displayItems: proposals, + }); + } else { + proposals.forEach((item) => { + if (item.title.toLowerCase().includes(value)) { + results.push(item); + } + }); + + this.setState({ + displayItems: results, + }); + } + }; + + handleButtonClick = (name) => { + const proposals = this.state.userProposals; + const allProposals = this.state.allProposals; + + let results = []; + + switch (name) { + case "All": + this.setState({ + displayItems: allProposals, + }); + break; + case "Accepted": + proposals.forEach((item) => { + if (item.proposalStatus === "ACCEPTED") { + results.push(item); + } + }); + this.setState({ + displayItems: results, + }); + break; + case "Submitted": + proposals.forEach((item) => { + if (item.proposalStatus === "SUBMITTED") { + results.push(item); + } + }); + this.setState({ + displayItems: results, + }); + break; + case "Draft": + proposals.forEach((item) => { + if (item.proposalStatus === "DRAFT") { + results.push(item); + } + }); + this.setState({ + displayItems: results, + }); + break; + case "Rejected": + proposals.forEach((item) => { + if (item.proposalStatus === "REJECTED") { + results.push(item); + } + }); + this.setState({ + displayItems: results, + }); + break; + } + }; + render() { return (
@@ -17,6 +122,7 @@ class DashboardContent extends Component { as="input" placeholder="search" className="searchbar" + onChange={this.handleSearchBarChange} />
@@ -25,22 +131,44 @@ class DashboardContent extends Component {
- - - - -
@@ -50,41 +178,88 @@ class DashboardContent extends Component {
-
-
-
- icon -
-
-

Sample Proposal

-

June 5, 2018 4:31 AM

+ {this.state.displayItems.map((proposalItem, index) => { + return ( +
+
+
+ icon +
+
+

{proposalItem.title}

+

{proposalItem.createdAt}

+
+ {proposalItem.proposalStatus === "DRAFT" ? ( + + ) : ( + + )} +
+
+
+ {proposalItem.proposalDescription} +
+
+ {proposalItem.creator === this.state.userId ? ( + + + + ) : null} + + + +
+
- -
-
-
- ex sit ex laboris adipisicing enim eiusmod proident - exercitation ea fugiat in llit pariatur occaecat ut nostrud - ullamco ex official ex sit ex laboris adipisicing enim eiusmod - proident exercitation ea... -
-
- - -
-
-
+ ); + })}
@@ -92,4 +267,12 @@ class DashboardContent extends Component { } } -export default DashboardContent; +const mapStateToProps = (state) => ({ + allProposals: state.proposal.allProposals, + userProposals: state.proposal.userProposals, +}); + +export default connect(mapStateToProps, { + getProposalsByUser, + getAllProposals, +})(DashboardContent); diff --git a/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.scss b/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.scss index 2577b135..a9e787f9 100644 --- a/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.scss +++ b/src/user/proposals/UserProposalDashboard/DashboardContent/DashboardContent.scss @@ -112,6 +112,16 @@ height: 30px; cursor: default; } + .status-btn-submitted { + background-color: white; + padding: 4px 36px; + border: solid 1px #90949c; + border-radius: 100px; + color: #90949c; + margin: 0 5px; + height: 30px; + cursor: default; + } .dropdown-container { margin-left: auto; margin-right: 5px; diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.js b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.js index 106355b4..d815fd99 100644 --- a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.js +++ b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.js @@ -1,7 +1,7 @@ import React, { Component } from "react"; import "./DashboardRightPanel.scss"; import Comments from "./Comments/Comments"; -import OtherIdeas from "./OtherIdeas/OtherIdeas"; +import Notifications from "./Notifications/Notifications"; class DashboardRightPanel extends Component { constructor(props) { @@ -11,11 +11,8 @@ class DashboardRightPanel extends Component { render() { return (
-
- -
- +
); diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss index 133ebce0..159796a9 100644 --- a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss +++ b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/DashboardRightPanel.scss @@ -1,12 +1,8 @@ .panel { display: flex; - flex-direction: column; - .panel-comments { - flex-grow: 1; - } .panel-ideas { margin-top: 10px; - flex-grow: 1; + height: 100%; } } diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/Notifications.js b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/Notifications.js new file mode 100644 index 00000000..422c39fb --- /dev/null +++ b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/Notifications.js @@ -0,0 +1,142 @@ +import React, { Component } from "react"; +import "./OtherIdeas.scss"; +import { ListGroup, Image } from "react-bootstrap"; +import userIcon2 from "../../../../../images/userIcon2.jpg"; +import socket from "../../../../dashboard/utils/socket"; +import { connect } from "react-redux"; +import { getUserProposalNotifications } from "../../../../../actions/proposalActions"; +import { getProposalNotifications } from "../../../../../actions/notificationAction"; + +class Notifications extends Component { + constructor(props) { + super(props); + this.state = { + socket: socket, + notifications: [], + }; + } + + componentDidMount() { + const data = { + userId: localStorage.getItem("userId"), + }; + + this.props.getProposalNotifications(); + this.props.getUserProposalNotifications(data); + + this.state.socket.on("new proposal created", (data) => { + data.newNotification = true; + data.createdAt = new Date().toString().substring(0, 24); + this.setState({ + notifications: [...this.state.notifications, data], + }); + }); + + this.state.socket.on("proposal deleted", (data) => { + data.newNotification = true; + data.createdAt = new Date().toString().substring(0, 24); + this.setState({ + notifications: [...this.state.notifications, data], + }); + }); + + this.state.socket.on("proposal submitted", (data) => { + data.newNotification = true; + data.createdAt = new Date().toString().substring(0, 24); + this.setState({ + notifications: [...this.state.notifications, data], + }); + }); + } + + componentWillReceiveProps(nextProps) { + nextProps.proposalNotifications.forEach((notification, index) => { + let createdTime = new Date(notification.createdAt) + .toString() + .substring(0, 24); + notification.createdAt = createdTime.toString(); + }); + + this.setState( + { + notifications: [ + ...this.state.notifications, + ...nextProps.proposalNotifications, + ...nextProps.userProposalNotifications, + ], + }, + () => { + this.organizaNotifications(); + } + ); + } + + organizaNotifications = () => { + let notifications = this.state.notifications; + + notifications.sort((a, b) => { + return new Date(b.createdAt) - new Date(a.createdAt); + }); + + this.setState({ + Notifications: notifications, + }); + }; + + render() { + const notifications = [...this.state.notifications]; + return ( +
+
Notifications
+
+ + {notifications.map((notification, index) => { + return ( + +
+
+ icon +
+
+
+ {notification.heading} +
+ +
+ {notification.createdAt} +
+
+ {notification.content} +
+
+
+
+ ); + })} +
+
+
+ ); + } +} + +const mapStateToProps = (state) => ({ + proposalNotifications: state.notification.proposalNotifications, + userProposalNotifications: state.proposal.userNotifications, +}); + +export default connect(mapStateToProps, { + getUserProposalNotifications, + getProposalNotifications, +})(Notifications); diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/OtherIdeas.scss similarity index 95% rename from src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss rename to src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/OtherIdeas.scss index 6058404f..9f1c105c 100644 --- a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.scss +++ b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Notifications/OtherIdeas.scss @@ -11,10 +11,10 @@ } .ideas-container { border: solid 1px #dfe9f1; - overflow: auto; + min-height: 90vh; border-radius: 5px; margin: 5px; - max-height: 300px; + .idea-item { display: flex; padding: none; diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js deleted file mode 100644 index a64b31b3..00000000 --- a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/OtherIdeas/OtherIdeas.js +++ /dev/null @@ -1,119 +0,0 @@ -import React, { Component } from "react"; -import "./OtherIdeas.scss"; -import { ListGroup, Image } from "react-bootstrap"; -import userIcon2 from "../../../../../images/userIcon2.jpg"; - -class OtherIdeas extends Component { - constructor(props) { - super(props); - this.state = {}; - } - render() { - return ( -
-
Other Ideas
-
- - -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
- -
-
- icon -
-
-
We got into GSoC 2020
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed - do eiusmod tempor incididunt ut labore et dolore magna -
-
-
-
-
-
-
- ); - } -} - -export default OtherIdeas; diff --git a/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Utils/notifications.js b/src/user/proposals/UserProposalDashboard/DashboardRightPanel/Utils/notifications.js new file mode 100644 index 00000000..e69de29b