diff --git a/_test_/App.spec.js b/_test_/App.spec.js index a44161b..3654a0a 100644 --- a/_test_/App.spec.js +++ b/_test_/App.spec.js @@ -22,6 +22,6 @@ describe('App', () => { expect(app.find('Switch').length).toBe(1); }); it('renders a Route component', () => { - expect(app.find('Route').length).toBe(3); + expect(app.find('Route').length).toBe(5); }); }); diff --git a/_test_/Articles.spec.js b/_test_/Articles.spec.js new file mode 100644 index 0000000..ed7dd3f --- /dev/null +++ b/_test_/Articles.spec.js @@ -0,0 +1,24 @@ +import React from 'react'; +import expect from 'expect'; +import { shallow } from 'enzyme'; + +import Articles from '../src/views/Articles/Articles'; + +describe('App', () => { + let app; + beforeEach(() => { + app = shallow(); + }); + + it('renders successfully', () => { + expect(app).toBeDefined(); + }); + + it('renders a div component', () => { + expect(app.find('div').length).toBe(1); + }); + + it('tags have classes', () => { + expect(app.find('_class').length).toBe(35); + }); +}); diff --git a/_test_/Card.spec.js b/_test_/Card.spec.js new file mode 100644 index 0000000..dca0749 --- /dev/null +++ b/_test_/Card.spec.js @@ -0,0 +1,24 @@ +import React from 'react'; +import expect from 'expect'; +import { shallow, mount } from 'enzyme'; + +import Card from '../src/components/Card'; + + +describe('App', () => { + let app; + beforeEach(() => { + app = shallow(); + }); + + it('renders successfully', () => { + expect(app).toBeDefined(); + }); + it('renders a div component', () => { + expect(app.find('div').length).toBe(1); + }); + + it('renders classNames component', () => { + expect(app.find('_class').length).toBe(7); + }); +}); diff --git a/_test_/Dropdown.spec.js b/_test_/Dropdown.spec.js new file mode 100644 index 0000000..9df5cc3 --- /dev/null +++ b/_test_/Dropdown.spec.js @@ -0,0 +1,18 @@ +import React from 'react'; +import expect from 'expect'; +import { shallow } from 'enzyme'; + +import Dropdown from '../src/components/Dropdown'; + + +describe('App', () => { + let app; + beforeEach(() => { + app = shallow(); + }); + + it('renders successfully', () => { + expect(app).toBeDefined(); + }); + +}); diff --git a/_test_/Homepage.spec.js b/_test_/Homepage.spec.js index 83a0043..fc92819 100644 --- a/_test_/Homepage.spec.js +++ b/_test_/Homepage.spec.js @@ -30,12 +30,12 @@ describe('App', () => { expect(app.find('ul').length).toBe(1); }); it('renders a li component', () => { - expect(app.find('li').length).toBe(2); + expect(app.find('li').length).toBe(3); }); it('renders a br component', () => { - expect(app.find('br').length).toBe(2); + expect(app.find('br').length).toBe(4); }); it('renders a Link component', () => { - expect(app.find('Link').length).toBe(2); + expect(app.find('Link').length).toBe(3); }); }); diff --git a/_test_/Login.spec.js b/_test_/Login.spec.js index 6cdfa5c..1529e54 100644 --- a/_test_/Login.spec.js +++ b/_test_/Login.spec.js @@ -13,26 +13,4 @@ describe('App', () => { it('renders successfully', () => { expect(app).toBeDefined(); }); - - it('renders a div component', () => { - expect(app.find('div').length).toBe(1); - }); - - it('renders a h1 component', () => { - expect(app.find('h1').length).toBe(1); - }); - - it('renders a h3 component', () => { - expect(app.find('h3').length).toBe(1); - }); - - it('renders a ul component', () => { - expect(app.find('ul').length).toBe(1); - }); - it('renders a li component', () => { - expect(app.find('li').length).toBe(1); - }); - it('renders a Link component', () => { - expect(app.find('Link').length).toBe(1); - }); }); diff --git a/_test_/RatingsModal.spec.js b/_test_/RatingsModal.spec.js new file mode 100644 index 0000000..a676dab --- /dev/null +++ b/_test_/RatingsModal.spec.js @@ -0,0 +1,41 @@ +import React from 'react'; +import expect from 'expect'; +import { shallow } from 'enzyme'; + +import RatingsModal from '../src/components/RatingsModal'; + + +describe('App', () => { + let app; + beforeEach(() => { + app = shallow(); + }); + + it('renders successfully', () => { + expect(app).toBeDefined(); + console.log(app.debug()) + }); + + it('tags have classes', () => { + expect(app.find('_class').length).toBe(9); + }); + + it('renders a span tag', () => { + expect(app.find('span').length).toBe(1); + }); + + it('renders a div', () => { + expect(app.find('div').length).toBe(1); + }); + + it('renders a h2 tag', () => { + expect(app.find('h2').length).toBe(1); + }); + + it('renders StarRatingComponent', () => { + expect(app.find('StarRatingComponent').length).toBe(1); + }); +}); + + + diff --git a/_test_/ReadArticle.spec.js b/_test_/ReadArticle.spec.js new file mode 100644 index 0000000..7477b35 --- /dev/null +++ b/_test_/ReadArticle.spec.js @@ -0,0 +1,16 @@ +import React from 'react'; +import expect from 'expect'; +import { shallow } from 'enzyme'; + +import ReadArticles from '../src/views/Articles/ReadArticle'; + +describe('App', () => { + let app; + beforeEach(() => { + app = shallow(); + }); + + it('renders successfully', () => { + expect(app).toBeDefined(); + }); +}); diff --git a/package-lock.json b/package-lock.json index 133380f..8e86bb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -789,6 +789,24 @@ "regexpu-core": "^4.5.4" } }, + "@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + } + } + }, "@babel/preset-env": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", @@ -1711,6 +1729,39 @@ "@types/yargs": "^12.0.9" } }, + "@react-bootstrap/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@react-bootstrap/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-4l3q7LcZEhrSkI4d3Ie3g4CdrXqqTexXX4PFT45CB0z5z2JUbaxgRwKNq7r5j2bLdVpZm+uvUGqxJw8d9vgbJQ==", + "requires": { + "babel-runtime": "6.x.x", + "create-react-context": "^0.2.1", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.5", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "@restart/context": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz", + "integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==" + }, + "@restart/hooks": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.9.tgz", + "integrity": "sha512-6gL84qcdZHUN0V5czyMXzAbcBBpHm8H5Gwj7eqnVi6p3JzGwJ5m2at19dKE9Gv3SsU3Hv9SPDX+6zQSExCjjkQ==" + }, "@types/babel__core": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz", @@ -2129,6 +2180,11 @@ "function-bind": "^1.1.1" } }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -2644,7 +2700,6 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -2653,14 +2708,12 @@ "core-js": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" }, "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" } } }, @@ -2909,6 +2962,20 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "bootstrap-4-react": { + "version": "0.0.59", + "resolved": "https://registry.npmjs.org/bootstrap-4-react/-/bootstrap-4-react-0.0.59.tgz", + "integrity": "sha512-j3a618tWHl/ajYQi6zn0LdVfksRH+gyQ4RwIanTPin6xkHkgYfk+47ZlHFSwyiO9zVFn4xznoGjTwWA0AIlJkA==", + "requires": { + "bootstrap-4-required": "0.0.1", + "fsts": "0.0.44" + } + }, + "bootstrap-4-required": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/bootstrap-4-required/-/bootstrap-4-required-0.0.1.tgz", + "integrity": "sha512-4S6Trn9pRVSR756GRYr3hy2cZL3Vc0tw0/H9E+mbNeOR+4tn6CeRgcLx0YqZmL2XlabtEV73+XAesmwkgTDKvQ==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3234,6 +3301,11 @@ } } }, + "change-emitter": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz", + "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU=" + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -3313,6 +3385,11 @@ } } }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, "clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", @@ -3653,6 +3730,15 @@ "sha.js": "^2.4.8" } }, + "create-react-context": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", + "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4196,6 +4282,14 @@ "utila": "~0.4" } }, + "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" + } + }, "dom-serializer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", @@ -4293,6 +4387,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.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -5199,6 +5301,27 @@ "bser": "^2.0.0" } }, + "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=" + } + } + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -5724,28 +5847,28 @@ "dependencies": { "abbrev": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "resolved": false, "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "resolved": false, "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true, "optional": true }, "aproba": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "resolved": false, "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "resolved": false, "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "optional": true, @@ -5756,14 +5879,14 @@ }, "balanced-match": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "resolved": false, "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true, "optional": true }, "brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "optional": true, @@ -5774,42 +5897,42 @@ }, "chownr": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "resolved": false, "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "resolved": false, "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true, "optional": true }, "concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "resolved": false, "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true, "optional": true }, "console-control-strings": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "resolved": false, "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true, "optional": true }, "core-util-is": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "resolved": false, "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "optional": true, @@ -5819,28 +5942,28 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "resolved": false, "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "resolved": false, "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "resolved": false, "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "resolved": false, "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, @@ -5850,14 +5973,14 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "resolved": false, "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "resolved": false, "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, @@ -5874,7 +5997,7 @@ }, "glob": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "resolved": false, "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "optional": true, @@ -5889,14 +6012,14 @@ }, "has-unicode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "resolved": false, "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "resolved": false, "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "optional": true, @@ -5906,7 +6029,7 @@ }, "ignore-walk": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "resolved": false, "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, @@ -5916,7 +6039,7 @@ }, "inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "resolved": false, "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, @@ -5927,21 +6050,21 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true, "optional": true }, "ini": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "resolved": false, "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "optional": true, @@ -5951,14 +6074,14 @@ }, "isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "resolved": false, "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "optional": true, @@ -5968,14 +6091,14 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": false, "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true, "optional": true }, "minipass": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "optional": true, @@ -5986,7 +6109,7 @@ }, "minizlib": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "resolved": false, "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "dev": true, "optional": true, @@ -5996,7 +6119,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "optional": true, @@ -6006,14 +6129,14 @@ }, "ms": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "resolved": false, "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true, "optional": true }, "needle": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", + "resolved": false, "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", "dev": true, "optional": true, @@ -6025,7 +6148,7 @@ }, "node-pre-gyp": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", + "resolved": false, "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", "dev": true, "optional": true, @@ -6044,7 +6167,7 @@ }, "nopt": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "resolved": false, "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, @@ -6055,14 +6178,14 @@ }, "npm-bundled": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "resolved": false, "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", + "resolved": false, "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", "dev": true, "optional": true, @@ -6073,7 +6196,7 @@ }, "npmlog": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "resolved": false, "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, @@ -6086,21 +6209,21 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "resolved": false, "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "resolved": false, "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "optional": true, @@ -6110,21 +6233,21 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": false, "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "resolved": false, "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, @@ -6135,21 +6258,21 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": false, "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "resolved": false, "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "resolved": false, "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "optional": true, @@ -6162,7 +6285,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": false, "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true @@ -6171,7 +6294,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": false, "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -6187,7 +6310,7 @@ }, "rimraf": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "resolved": false, "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "optional": true, @@ -6197,49 +6320,49 @@ }, "safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "resolved": false, "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "optional": true }, "safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "resolved": false, "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "resolved": false, "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "resolved": false, "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "resolved": false, "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "resolved": false, "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "optional": true, @@ -6251,7 +6374,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": false, "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -6261,7 +6384,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": false, "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "optional": true, @@ -6271,14 +6394,14 @@ }, "strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "resolved": false, "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "resolved": false, "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", "dev": true, "optional": true, @@ -6294,14 +6417,14 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "resolved": false, "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "resolved": false, "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "optional": true, @@ -6311,14 +6434,14 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "resolved": false, "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true }, "yallist": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "resolved": false, "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", "dev": true, "optional": true @@ -6336,6 +6459,11 @@ "rimraf": "2" } }, + "fsts": { + "version": "0.0.44", + "resolved": "https://registry.npmjs.org/fsts/-/fsts-0.0.44.tgz", + "integrity": "sha512-0U4qvbzOE+3s2711DdszIyaAnZ3M0dbFAhnkez/ITy31MwzDI2lepGSkVeFOyx6jqWvwaSZr01RP4hdM4I8wxQ==" + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -7723,8 +7851,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-string": { "version": "1.0.4", @@ -7794,6 +7921,15 @@ } } }, + "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", @@ -9632,6 +9768,11 @@ "object.assign": "^4.1.0" } }, + "keycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz", + "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ=" + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -10274,6 +10415,15 @@ "lower-case": "^1.1.1" } }, + "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.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", @@ -11063,6 +11213,11 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, + "popper.js": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz", + "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==" + }, "portfinder": { "version": "1.0.21", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.21.tgz", @@ -11276,6 +11431,14 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "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" + } + }, "prompts": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", @@ -11306,6 +11469,25 @@ "reflect.ownkeys": "^0.2.0" } }, + "prop-types-extra": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz", + "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==", + "requires": { + "react-is": "^16.3.2", + "warning": "^3.0.0" + }, + "dependencies": { + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -11486,6 +11668,33 @@ "scheduler": "^0.13.6" } }, + "react-bootstrap": { + "version": "1.0.0-beta.10", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.10.tgz", + "integrity": "sha512-hSvUrVbm+2uEpsGLVbAKJe/HOBT8ou+AX8Oo3VHlXSbG/9dHonwNP/wXu1NcsJ+TemMk7UnzdX2J8BN5MDnIxA==", + "requires": { + "@babel/runtime": "^7.4.2", + "@react-bootstrap/react-popper": "1.2.1", + "@restart/context": "^2.1.4", + "@restart/hooks": "^0.3.0", + "classnames": "^2.2.6", + "dom-helpers": "^3.4.0", + "invariant": "^2.2.4", + "keycode": "^2.2.0", + "popper.js": "^1.14.7", + "prop-types": "^15.7.2", + "prop-types-extra": "^1.1.0", + "react-overlays": "^1.2.0", + "react-transition-group": "^4.0.0", + "uncontrollable": "^7.0.0", + "warning": "^4.0.3" + } + }, + "react-context-toolbox": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-context-toolbox/-/react-context-toolbox-2.0.2.tgz", + "integrity": "sha512-tY4j0imkYC3n5ZlYSgFkaw7fmlCp3IoQQ6DxpqeNHzcD0hf+6V+/HeJxviLUZ1Rv1Yn3N3xyO2EhkkZwHn0m1A==" + }, "react-dom": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", @@ -11502,6 +11711,75 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-notify-toast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/react-notify-toast/-/react-notify-toast-0.5.0.tgz", + "integrity": "sha1-sAz1CjzJeh0iLs19eo5/FL71+mc=", + "requires": { + "object-assign": "^4.0.0", + "prop-types": "^15.5.8" + } + }, + "react-overlays": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz", + "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==", + "requires": { + "classnames": "^2.2.6", + "dom-helpers": "^3.4.0", + "prop-types": "^15.6.2", + "prop-types-extra": "^1.1.0", + "react-context-toolbox": "^2.0.2", + "react-popper": "^1.3.2", + "uncontrollable": "^6.0.0", + "warning": "^4.0.2" + }, + "dependencies": { + "uncontrollable": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.2.3.tgz", + "integrity": "sha512-VgOAoBU2ptCL2bfTG2Mra0I8i1u6Aq84AFonD5tmCAYSfs3hWvr2Rlw0q2ntoxXTHjcQOmZOh3FKaN+UZVyREQ==", + "requires": { + "@babel/runtime": "^7.4.5", + "invariant": "^2.2.4" + } + } + } + }, + "react-popper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz", + "integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==", + "requires": { + "@babel/runtime": "^7.1.2", + "create-react-context": "<=0.2.2", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + }, + "dependencies": { + "create-react-context": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz", + "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + } + }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + } + } + }, "react-redux": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.0.tgz", @@ -11546,6 +11824,15 @@ "tiny-warning": "^1.0.0" } }, + "react-star-rating-component": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/react-star-rating-component/-/react-star-rating-component-1.4.1.tgz", + "integrity": "sha512-i0YEvQzToS0s0GDkxn01Jy4EeLpVEyh023NXJTJ+/1+xkvhpACyD4d1YeBhYWZab53ppUnUxs5gmp75gJr3khA==", + "requires": { + "classnames": "^2.2.5", + "prop-types": "^15.6.1" + } + }, "react-test-renderer": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz", @@ -11557,6 +11844,17 @@ "scheduler": "^0.13.6" } }, + "react-transition-group": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.2.2.tgz", + "integrity": "sha512-uP0tjqewtvjb7kGZFpZYPoD/NlVZmIgts9eTt1w35pAaEApPxQGv94lD3VkqyXf2aMqrSGwhs6EV/DLaoKbLSw==", + "requires": { + "@babel/runtime": "^7.4.5", + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", @@ -11955,6 +12253,26 @@ "util.promisify": "^1.0.0" } }, + "recompose": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.30.0.tgz", + "integrity": "sha512-ZTrzzUDa9AqUIhRk4KmVFihH0rapdCSMFXjhHbNrjAWxBuUD/guYlyysMnuHjlZC/KRiOKRtB4jf96yYSkKE8w==", + "requires": { + "@babel/runtime": "^7.0.0", + "change-emitter": "^0.1.2", + "fbjs": "^0.8.1", + "hoist-non-react-statics": "^2.3.1", + "react-lifecycles-compat": "^3.0.2", + "symbol-observable": "^1.0.4" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + } + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -13071,8 +13389,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.1", @@ -14012,6 +14329,16 @@ "mime-types": "~2.1.24" } }, + "typed-styles": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.5.tgz", + "integrity": "sha512-ht+rEe5UsdEBAa3gr64+QjUOqjOLJfWLvl5HZR5Ev9uo/OnD3p43wPeFSB1hNFc13GXQF/JU1Bn0YHLUqBRIlw==" + }, + "ua-parser-js": { + "version": "0.7.20", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", + "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" + }, "uglify-js": { "version": "3.4.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", @@ -14085,6 +14412,15 @@ } } }, + "uncontrollable": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.0.0.tgz", + "integrity": "sha512-HFhKHDACiAsTYoV3el/LP4PqcLzqyWrNRHE6nMdr0h8f7qbvTPXIN2S4q+tdfc64PHEXaSFBs/fKVB2+UwSYOA==", + "requires": { + "@babel/runtime": "^7.4.5", + "invariant": "^2.2.4" + } + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -14371,6 +14707,14 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", @@ -15741,6 +16085,11 @@ "iconv-lite": "0.4.24" } }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", diff --git a/package.json b/package.json index 22009ac..6313c86 100644 --- a/package.json +++ b/package.json @@ -22,16 +22,22 @@ }, "homepage": "https://github.com/andela/ah-nyati-frontend#readme", "dependencies": { + "bootstrap-4-react": "0.0.59", "css-loader": "^3.1.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", "expect": "^24.8.0", "express": "^4.17.1", "node-sass": "^4.12.0", + "prop-types": "^15.7.2", "react": "^16.8.6", + "react-bootstrap": "^1.0.0-beta.10", "react-dom": "^16.8.6", + "react-notify-toast": "^0.5.0", "react-redux": "^7.1.0", "react-router-dom": "^5.0.1", + "react-star-rating-component": "^1.4.1", + "recompose": "^0.30.0", "redux": "^4.0.4", "redux-thunk": "^2.3.0", "style-loader": "^0.23.1" @@ -40,6 +46,7 @@ "@babel/core": "^7.5.5", "@babel/plugin-proposal-class-properties": "^7.5.5", "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/polyfill": "^7.4.4", "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.5.5", diff --git a/src/actions/article.action.js b/src/actions/article.action.js new file mode 100644 index 0000000..52eea91 --- /dev/null +++ b/src/actions/article.action.js @@ -0,0 +1,33 @@ +import { notify } from 'react-notify-toast'; +import { FETCH_ARTICLE, RATE_ARTICLE } from './types'; +import { getArticle, rateArticle } from '../services/articles'; + +export const getAnArticle = article => ({ + type: FETCH_ARTICLE, + article, +}); + +export const rateAnArticle = rating => ({ + type: RATE_ARTICLE, + rating, +}); + + +export const getOneArticle = slug => dispatch => getArticle(slug).then((res) => { + if (res.status === 200) { + const { article } = res.data[0]; + dispatch(getAnArticle(article)); + } +}); +export const articleRating = (slug, rating) => dispatch => rateArticle(slug, rating).then((res) => { + if (res.status === 200) { + const { rating: newRating } = res.data[0]; + const { message } = res; + const data = { + newRating, + message, + }; + dispatch(rateAnArticle(data)); + notify.show((res.message), 'success'); + } +}); diff --git a/src/actions/types.js b/src/actions/types.js index 8edbdd7..3e4e7ee 100644 --- a/src/actions/types.js +++ b/src/actions/types.js @@ -1,2 +1,3 @@ export const FETCH_ARTICLE = 'FETCH_ARTICLE'; export const NEW_ARTICLE = 'NEW_ARTICLE'; +export const RATE_ARTICLE = 'RATE_ARTICLE'; diff --git a/src/components/App.js b/src/components/App.js index c10fdf2..1e89e79 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,18 +1,25 @@ import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; +import Notifications from 'react-notify-toast'; import Homepage from '../views/Homepage'; import Login from '../views/Login'; import Error from '../views/Error'; +import Articles from '../views/Articles/Articles'; +import ReadArticles from '../views/Articles/ReadArticle'; + /** * App component, renders all the other components. */ const App = () => (
+ + + diff --git a/src/components/Card.jsx b/src/components/Card.jsx new file mode 100644 index 0000000..8bc6e17 --- /dev/null +++ b/src/components/Card.jsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { + Card, ListGroup, +} from 'bootstrap-4-react'; +import PropTypes from 'prop-types'; + +/** + * This component is called card component, it renders the article in the ReadArticle component. + */ +const Cards = (props) => { + const { + title, body, slug, views, + } = props; + return ( +
+ + + {title} + + {body} + + + + {slug} + {views} + + +
+ ); +}; + +Cards.defaultProps = { + title: '', + body: '', + slug: '', + views: 0, +}; +Cards.propTypes = { + title: PropTypes.string, + body: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + slug: PropTypes.string, + views: PropTypes.number, +}; + +export default Cards; diff --git a/src/components/Dropdown.jsx b/src/components/Dropdown.jsx new file mode 100644 index 0000000..d5d6489 --- /dev/null +++ b/src/components/Dropdown.jsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { + Dropdown, ButtonGroup, +} from 'bootstrap-4-react'; + +/** + * This component is called DropRight component, it renders the dropdown component that holds + * the link to article rating modal. + */ +const DropRight = () => ( + + + + + + + + Report This Article + Rate this Article + Bookmark this Article + + +); +export default DropRight; diff --git a/src/components/RatingsModal.jsx b/src/components/RatingsModal.jsx new file mode 100644 index 0000000..5ed2973 --- /dev/null +++ b/src/components/RatingsModal.jsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { + Modal, Button, +} from 'bootstrap-4-react'; +import StarRatingComponent from 'react-star-rating-component'; +import PropTypes from 'prop-types'; + +/** + * This component is called RatingsModal component, it renders the ratings modal and also holds + * the button to close or save ratings. + */ +const RatingsModal = (props) => { + const { + title, rating, starClick, handleRatingsSubmit, + } = props; + return ( + + + + {title} + + + + + +
+

+Your current rating for this article is: + {' '} + {rating} + {' '} +stars +

+ +
+
+ + + + +
+
+ ); +}; + +RatingsModal.defaultProps = { + title: '', + starClick: () => '', + handleRatingsSubmit: () => '', + rating: 0, +}; + +RatingsModal.propTypes = { + title: PropTypes.string, + starClick: PropTypes.func, + handleRatingsSubmit: PropTypes.func, + rating: PropTypes.number, +}; + +export default RatingsModal; diff --git a/src/reducers/article.reducer.js b/src/reducers/article.reducer.js new file mode 100644 index 0000000..5967dda --- /dev/null +++ b/src/reducers/article.reducer.js @@ -0,0 +1,27 @@ +import { FETCH_ARTICLE, RATE_ARTICLE } from '../actions/types'; + +const initialState = { + article: {}, + rating: '', + alert: '', +}; + +const articles = (state = initialState, action) => { + switch (action.type) { + case FETCH_ARTICLE: + return { + ...state, + article: action.article, + }; + case RATE_ARTICLE: + return { + ...state, + rating: action.rating, + alert: action.message, + }; + default: + return state; + } +}; + +export default articles; diff --git a/src/reducers/index.js b/src/reducers/index.js index a67c94e..b856ed6 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -1,3 +1,9 @@ import { combineReducers } from 'redux'; +import articles from './article.reducer'; -export default combineReducers({ }); + +const reducers = combineReducers({ + articles, +}); + +export default reducers; diff --git a/src/services/articles.js b/src/services/articles.js new file mode 100644 index 0000000..885e188 --- /dev/null +++ b/src/services/articles.js @@ -0,0 +1,27 @@ +const defaultUrl = 'https://ah-nyati-backend-staging.herokuapp.com/api/v1'; +const { UserToken } = localStorage; + + +export const getArticle = slug => fetch(`${defaultUrl}/articles/${slug}`) + .then(resp => resp.json()) + .then(resp => resp) + .catch(err => err); + +export const rateArticle = (slug, rating) => { + const data = { + value: rating, + }; + const config = { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + token: UserToken, + }, + body: JSON.stringify(data), + }; + return fetch(`${defaultUrl}/articles/rate/${slug}`, config) + .then(resp => resp.json()) + .then(resp => (resp)) + .catch(err => err); +}; diff --git a/src/services/authentication.js b/src/services/authentication.js new file mode 100644 index 0000000..6cb30fd --- /dev/null +++ b/src/services/authentication.js @@ -0,0 +1,24 @@ +const defaultUrl = 'https://ah-nyati-backend-staging.herokuapp.com/api/v1'; + + +const login = (userData) => { + const config = { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(userData), + }; + + return fetch(`${defaultUrl}/auth/login`, config) + .then(resp => resp.json()) + .then((res) => { + if (res.status === 200) { + localStorage.UserToken = res.token; + } + }) + .catch(err => err); +}; + +export default login; diff --git a/src/views/Articles/Articles.jsx b/src/views/Articles/Articles.jsx new file mode 100644 index 0000000..0d55e0c --- /dev/null +++ b/src/views/Articles/Articles.jsx @@ -0,0 +1,88 @@ +import React, { Component } from 'react'; +import { Link } from 'react-router-dom'; +import { Card, BSmall } from 'bootstrap-4-react'; + + +/** + * Dummy get all articles component,renders all the articles in the database + */ +class Articles extends Component { + state = { + articles: [ + { + title: 'Article', + slug: 'article', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + catId: 1, + userId: 1, + }, + { + title: 'Article 2', + slug: 'article', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + catId: 1, + userId: 1, + }, + { + title: 'Article 3', + slug: 'article', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + catId: 1, + userId: 1, + }, + { + title: 'new Article', + slug: 'article new', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + catId: 1, + userId: 1, + }, + { + title: 'long Article', + slug: 'article longer', + body: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.', + catId: 1, + userId: 1, + }, + ], + } + + render() { + const { articles } = this.state; + const data = articles.map((article, i) => { + const elKey = `${i}-${article.slug}`; + return ( + + + {article.title} + + {article.body} + + + + + + +Click to read + + + + + + ); + }); + return ( +
+ {data} +
+ + ); + } +} + + +export default Articles; diff --git a/src/views/Articles/ReadArticle.jsx b/src/views/Articles/ReadArticle.jsx new file mode 100644 index 0000000..a3c7b34 --- /dev/null +++ b/src/views/Articles/ReadArticle.jsx @@ -0,0 +1,87 @@ +import React, { Component } from 'react'; +import { Modal } from 'bootstrap-4-react'; +import { connect } from 'react-redux'; +import { PropTypes } from 'prop-types'; +import { getOneArticle as getAnArticle, articleRating as articleRate } from '../../actions/article.action'; +import Cards from '../../components/Card'; +import DropRight from '../../components/Dropdown'; +import RatingsModal from '../../components/RatingsModal'; + +/** +* This is the Read component, it renders a single article with the necessary views like article rating. + */ +class ReadArticles extends Component { + constructor(props) { + super(props); + this.state = { + rating: 0, + }; + } + + componentDidMount() { + const { match } = this.props; + const { params: { slug } } = match; + const { getAnArticle } = this.props; + getAnArticle(slug); + } + + onStarClick = (nextValue) => { + this.setState({ rating: nextValue }); + } + +handleRatingsSubmit = () => { + const { match } = this.props; + const { params: { slug } } = match; + const { rating } = this.state; + const { articleRate } = this.props; + articleRate(slug, rating); +} + +render() { + const { articles: { article } } = this.props; + const { + title, slug, body, views, + } = article; + const { rating } = this.state; + return ( +
+ + + + + + + +
+ ); +} +} + +const mapStatetoProps = state => ({ + articles: state.articles, +}); + +ReadArticles.defaultProps = { + match: () => '', + title: '', +}; + +ReadArticles.propTypes = { + match: PropTypes.func, + getAnArticle: PropTypes.func.isRequired, + articleRate: PropTypes.func.isRequired, + articles: PropTypes.object.isRequired, + title: PropTypes.string, +}; + +export default connect(mapStatetoProps, { getAnArticle, articleRate })(ReadArticles); diff --git a/src/views/Homepage.jsx b/src/views/Homepage.jsx index 54ded55..feee75c 100644 --- a/src/views/Homepage.jsx +++ b/src/views/Homepage.jsx @@ -17,6 +17,11 @@ const Homepage = () => (
  • CLICK HERE TO SEE THE LOGIN PAGE
  • +
    +
    +
  • + Find all articles +
  • ); diff --git a/src/views/Login.jsx b/src/views/Login.jsx index 6ca8871..9b1b9ae 100644 --- a/src/views/Login.jsx +++ b/src/views/Login.jsx @@ -1,20 +1,75 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; +import React, { Component } from 'react'; +import { Redirect } from 'react-router-dom'; +import { Form, Button } from 'bootstrap-4-react'; +import login from '../services/authentication'; + /** * Dummy Login Page, should allow the user to log into the app successfully * it also holds the link to the dummy Home page */ -const Login = () => ( -
    -

    Welcome To Authors Haven Login Page.

    -

    Good to see you

    -
      -
    • - CLICK HERE TO GO BACK TO THE HOMEPAGE -
    • -
    -
    -); + +class Login extends Component { + constructor(props) { + super(props); + this.state = { + loginDetails: {}, + redirect: false, + }; + } + + onInputChange = (event) => { + const { loginDetails } = this.state; + loginDetails[event.target.id] = event.target.value; + this.setState({ loginDetails }); + }; + + onButtonSubmit = (event) => { + event.preventDefault(); + const { loginDetails } = this.state; + // const { login } = this.props; + login(loginDetails); + this.setState(prevState => ({ redirect: !prevState.redirect })); + }; + + render() { + const { loginDetails, redirect } = this.state; + return ( + <> +
    + + + + + + + + + +
    + {redirect && } + + ); + } +} + export default Login;