diff --git a/package-lock.json b/package-lock.json
index 2207e63b9..db958783b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1162,6 +1162,39 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
},
+ "@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.1",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.1.tgz",
+ "integrity": "sha512-kjGGlli8iTe5TFDw6qHZJ5QK1naITMveIO+o8yQJJqwX8VIkiQzLddK98Lduga2krJMzWlNqDR/4isGLiyBlUA=="
+ },
"@svgr/babel-plugin-add-jsx-attribute": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz",
@@ -1902,6 +1935,38 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
+ "axios": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
+ "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==",
+ "requires": {
+ "follow-redirects": "1.5.10",
+ "is-buffer": "^2.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
"axobject-query": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
@@ -2396,6 +2461,11 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
+ "bootstrap": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+ "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
+ },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -3327,6 +3397,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",
@@ -3677,6 +3752,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",
@@ -4234,6 +4318,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",
@@ -4360,6 +4452,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",
@@ -5200,6 +5300,35 @@
"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="
+ },
+ "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.1",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
@@ -5603,6 +5732,11 @@
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
},
+ "gud": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+ },
"gzip-size": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
@@ -5777,6 +5911,19 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
},
+ "history": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz",
+ "integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "loose-envify": "^1.2.0",
+ "resolve-pathname": "^2.2.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0",
+ "value-equal": "^0.4.0"
+ }
+ },
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -5787,6 +5934,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "hoist-non-react-statics": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
+ "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ },
"hosted-git-info": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
@@ -6378,6 +6533,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",
@@ -7701,6 +7865,11 @@
"array-includes": "^3.0.3"
}
},
+ "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",
@@ -8134,6 +8303,16 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
+ "mini-create-react-context": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz",
+ "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==",
+ "requires": {
+ "@babel/runtime": "^7.4.0",
+ "gud": "^1.0.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
"mini-css-extract-plugin": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
@@ -8330,6 +8509,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",
@@ -8983,6 +9171,11 @@
"ts-pnp": "^1.0.0"
}
},
+ "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.20",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
@@ -9924,6 +10117,25 @@
"react-is": "^16.8.1"
}
},
+ "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"
+ }
+ }
+ }
+ },
"property-information": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.1.0.tgz",
@@ -10096,6 +10308,33 @@
"whatwg-fetch": "3.0.0"
}
},
+ "react-bootstrap": {
+ "version": "1.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.9.tgz",
+ "integrity": "sha512-M0BYLuuUdMITJ16+DDDb1p4vWV87csEBi/uOxZYODuDZh7hvbrJVahfvPXcqeqq4eEpNL+PKSlqb9fNaY0HZyA==",
+ "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": "^6.1.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-dev-utils": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.0.1.tgz",
@@ -10194,6 +10433,96 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA=="
},
+ "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"
+ }
+ },
+ "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-router": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz",
+ "integrity": "sha512-EM7suCPNKb1NxcTZ2LEOWFtQBQRQXecLxVpdsP4DW4PbbqYWeRiLyV/Tt1SdCrvT2jcyXAXmVTmzvSzrPR63Bg==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "hoist-non-react-statics": "^3.1.0",
+ "loose-envify": "^1.3.1",
+ "mini-create-react-context": "^0.3.0",
+ "path-to-regexp": "^1.7.0",
+ "prop-types": "^15.6.2",
+ "react-is": "^16.6.0",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "requires": {
+ "isarray": "0.0.1"
+ }
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.0.1.tgz",
+ "integrity": "sha512-zaVHSy7NN0G91/Bz9GD4owex5+eop+KvgbxXsP/O+iW1/Ln+BrJ8QiIR5a6xNPtrdTvLkxqlDClx13QO1uB8CA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "history": "^4.9.0",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.6.2",
+ "react-router": "5.0.1",
+ "tiny-invariant": "^1.0.2",
+ "tiny-warning": "^1.0.0"
+ }
+ },
"react-scripts": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.0.1.tgz",
@@ -10254,6 +10583,27 @@
"workbox-webpack-plugin": "4.2.0"
}
},
+ "react-transition-group": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.1.1.tgz",
+ "integrity": "sha512-K/N1wqJ2GRP2yj3WBqEUYa0KV5fiaAWpUfU9SpHOHefeKvyrO+VrnMBML21M19QZoVbDZKmuQFHZYoMMi1xuJA==",
+ "requires": {
+ "@babel/runtime": "^7.4.5",
+ "dom-helpers": "^3.4.0",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
+ "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ }
+ }
+ }
+ },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -10575,6 +10925,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
},
+ "resolve-pathname": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz",
+ "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg=="
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -11685,6 +12040,16 @@
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
},
+ "tiny-invariant": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.4.tgz",
+ "integrity": "sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g=="
+ },
+ "tiny-warning": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.2.tgz",
+ "integrity": "sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q=="
+ },
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
@@ -11821,11 +12186,21 @@
"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=="
+ },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
+ "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",
@@ -11847,6 +12222,25 @@
}
}
},
+ "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"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
+ "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ }
+ }
+ }
+ },
"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",
@@ -12122,6 +12516,11 @@
"spdx-expression-parse": "^3.0.0"
}
},
+ "value-equal": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz",
+ "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw=="
+ },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -12212,6 +12611,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",
diff --git a/package.json b/package.json
index e7e4a7c62..e092f2f8c 100644
--- a/package.json
+++ b/package.json
@@ -3,8 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "axios": "^0.19.0",
+ "bootstrap": "^4.3.1",
"react": "^16.8.6",
+ "react-bootstrap": "^1.0.0-beta.9",
"react-dom": "^16.8.6",
+ "react-router-dom": "^5.0.1",
"react-scripts": "3.0.1"
},
"scripts": {
@@ -12,5 +16,17 @@
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
}
}
diff --git a/src/App.css b/src/App.css
index c5c6e8a68..d81badff8 100644
--- a/src/App.css
+++ b/src/App.css
@@ -1,28 +1,91 @@
-.App {
+@import url('https://fonts.googleapis.com/css?family=Limelight&display=swap');
+
+.nav_container {
+ background: #300701 url("https://i.kinja-img.com/gawker-media/image/upload/s--m9daP_xN--/c_scale,f_auto,fl_progressive,q_80,w_800/unsnbwg2cke5spzlpsuy.jpg") no-repeat center top;
+ background-size: 100% 180%;
+ display: flex;
+ flex-direction: column;
+ height: 15rem;
+}
+
+.brand {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ text-shadow:
+ -1px -1px 0 white,
+ 1px -1px 0 white,
+ -1px 1px 0 white,
+ 1px 1px 0 white;
+ color: black;
+ font-size: 6rem;
+ text-decoration-line: none;
+ margin-left: 1rem;
text-align: center;
+ margin-top: 20px;
+ font-family: 'Limelight', cursive;
}
-.App-logo {
- animation: App-logo-spin infinite 20s linear;
- height: 80px;
+.nav {
+ display: flex;
+ justify-content: center;
}
-.App-header {
- background-color: #222;
- height: 150px;
- padding: 20px;
+.nav_link {
+ font-family: 'Limelight', cursive;
color: white;
+ text-shadow:
+ -1px -1px 0 #000,
+ 1px -1px 0 #000,
+ -1px 1px 0 #000,
+ 1px 1px 0 #000;
+ font-size: 2rem;
+ text-decoration: none;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+.nav_link:first-child {
+ border-left: none;
}
-.App-title {
- font-size: 1.5em;
+.nav_link:hover {
+ color: red;
+ text-shadow:
+ -1px -1px 0 #990708,
+ 1px -1px 0 #990708,
+ -1px 1px 0 #990708,
+ 1px 1px 0 #990708;
+ text-decoration: none;
}
-.App-intro {
- font-size: large;
+.brand:hover {
+ color: #990708;
+ text-shadow:
+ -1px -1px 0 red,
+ 1px -1px 0 red,
+ -1px 1px 0 red,
+ 1px 1px 0 red;
+ text-decoration: none;
}
-@keyframes App-logo-spin {
- from { transform: rotate(0deg); }
- to { transform: rotate(360deg); }
+#rentalSection {
+ border-top: 10px solid black;
+ background: white;
+ padding-bottom: 15px;
}
+
+.currently-selected {
+ font-size: 1em;
+ text-align: center;
+ margin-left: 500px;
+ margin-right: 500px;
+ background-color: #FEE1A8;
+ border: 4px dotted black;
+ margin-top: 1rem;
+ padding: 15px;
+}
+
+.rentalHeader {
+ font-size: 2em;
+}
\ No newline at end of file
diff --git a/src/App.js b/src/App.js
index 203067e4d..0e6a437dd 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,21 +1,355 @@
import React, { Component } from 'react';
-import logo from './logo.svg';
+import 'bootstrap/dist/css/bootstrap.min.css';
+import Nav from 'react-bootstrap/Nav';
+import Button from 'react-bootstrap/Button';
+import { BrowserRouter as Router, Route, Link } from "react-router-dom";
+import Search from './components/Search';
+import Library from './components/Library';
+import Customers from './components/Customers';
+import OverdueMovies from './components/OverdueMovies';
+import axios from 'axios';
import './App.css';
class App extends Component {
+ constructor() {
+ super();
+
+ this.state = {
+ movies: [],
+ expandedMovies: {},
+ customers: [],
+ expandedCustomers: {},
+ deselectedMovie: null,
+ rentedMovie: undefined,
+ chosenCustomer: undefined,
+ deselectedCustomer: null,
+ dueDate: undefined,
+ checkoutDate: undefined,
+ currentRental: {
+ count: undefined,
+ movie: undefined,
+ customer: undefined,
+ checkin: false,
+ },
+ allRentals: undefined,
+ // customerRentals: undefined,
+ overdueMovies: undefined,
+ error: null,
+ };
+ }
+
+ componentDidMount() {
+ axios.get('http://localhost:3001/movies')
+ .then((response) => {
+ this.setState({ movies: response.data });
+ })
+ .catch((error) => {
+ this.setState({ error: error.message });
+ });
+
+ axios.get('http://localhost:3001/customers')
+ .then((response) => {
+ this.setState({ customers: response.data });
+ })
+ .catch((error) => {
+ this.setState({ error: error.message });
+ });
+ }
+
+ addMovieCallback = (movie) => {
+ const movieIds = this.state.movies.map(movie => movie.id)
+ this.setState({
+ movies: [...this.state.movies, {...movie, id: Math.max(...movieIds) + 1}]
+ });
+ }
+
+ onClickMovieDetailsCallback = (id) => {
+ const movie = this.state.movies.find(movie => movie.id === id);
+ const title = movie.title;
+
+ axios.get("http://localhost:3001/movies/" + title)
+ .then((response) => {
+ this.setState({
+ expandedMovies: {
+ ...response.data,
+ }
+ });
+ })
+ .catch((error) => {
+ this.setState({error: error.message})
+ });
+ }
+
+ onCloseMovieDetailsCallback = () => {
+ this.setState({
+ expandedMovies: null
+ });
+ }
+
+ onSelectMovieCallback = (id) => {
+ const selectedMovie = this.state.movies.find(movie => movie.id === id);
+ this.setState({
+ rentedMovie: selectedMovie,
+ deselectedMovie: null
+ });
+ }
+
+ onDeselectMovieCallback = (id) => {
+ const deselectedMovie = this.state.movies.find(movie => movie.id === id);
+
+ this.setState({
+ deselectedMovie: deselectedMovie,
+ rentedMovie: null,
+ });
+ }
+
+
+ onClickCustomerRentalsCallback = (id) => {
+ this.setState((prevState) => ({
+ expandedCustomers: {
+ ...prevState.expandedCustomers,
+ [id]: !prevState.expandedCustomers[id],
+ }
+ }));
+ }
+
+ onSelectCustomerCallback = (id) => {
+ const selectedCustomer = this.state.customers.find(customer => customer.id === id);
+ this.setState({
+ deselectedCustomer: null,
+ chosenCustomer: selectedCustomer
+ });
+ }
+
+ onDeselectCustomerCallback = (id) => {
+ const deselectedCustomer = this.state.customers.find(customer => customer.id === id);
+ this.setState({
+ chosenCustomer: null,
+ deselectedCustomer
+ });
+ }
+
+ rentMovie = () => {
+ const checkoutDate = new Date();
+ const dueDate = new Date();
+ dueDate.setDate(dueDate.getDate() + 1 );
+
+ const url = `http://localhost:3001/rentals/${this.state.rentedMovie.title}/check-out`;
+
+ const params = {
+ due_date: dueDate,
+ customer_id: this.state.chosenCustomer.id,
+ }
+
+ axios.post(url, params)
+ .then((response)=> {
+ this.setState((prevState) => ({
+ dueDate: dueDate,
+ checkoutDate: checkoutDate,
+ currentRental: {
+ ...prevState.currentRental,
+ count: response.data["rental"],
+ movie: prevState.rentedMovie.title,
+ customer: prevState.chosenCustomer.id,
+ }
+ }))
+
+ this.onRentCallback()
+ })
+ .catch((error) => {
+ this.setState({
+ error: error.message
+ })
+ })
+ }
+
+ onRentCallback = () => {
+ this.setState({
+ rentedMovie: undefined,
+ chosenCustomer: undefined,
+ dueDate: undefined,
+ checkoutDate: undefined,
+ })
+ }
+
+ checkinMovie = () => {
+ const url = `http://localhost:3001/rentals/${this.state.currentRental.movie}/return`;
+
+ const params = {
+ customer_id: this.state.currentRental.customer,
+ }
+
+ axios.post(url, params)
+ .then(() => {
+ this.setState((prevState) => ({
+ currentRental: {
+ ...prevState.currentRental,
+ count: undefined,
+ movie: undefined,
+ customer: undefined,
+ checkin: true,
+ }
+ }))
+ })
+ .catch((error) => {
+ this.setState({
+ error: error.message
+ })
+ })
+ }
+
+ setOverdueMoviesCallback = (value) => {
+ this.setState({
+ overdueMovies: value
+ })
+ }
+
+ setErrorOverdueCallback = (error) => {
+ this.setState({
+ error: error.message
+ });
+ }
+
+ onCustomerRentalsCallback = (customerID) => {
+ let uniqueRentals = {}
+
+ axios.get('http://localhost:3001/rentals')
+ .then((response) => {
+ response.data.forEach((rental, i) => {
+ if (rental !== null) {
+ uniqueRentals[i] = {
+ "customer": rental.customer_id,
+ "movie": rental.title,
+ "checkout_date": rental.checkout_date,
+ "due_date": rental.due_date
+ }
+ }
+ })
+
+ this.setState({
+ allRentals: uniqueRentals
+ })
+
+ // this.findCustomerRentals(customerID)
+ this.onClickCustomerRentalsCallback(customerID)
+ })
+ .catch((error) => {
+ this.setState({
+ error: error.message
+ });
+ });
+ }
+
render() {
+ const errorSection = (this.state.error) ?
+ (
Movie: {this.state.rentedMovie.title}
} + + { this.state.chosenCustomer &&Customer: {this.state.chosenCustomer.name}
} + + { this.state.chosenCustomer && this.state.rentedMovie && } +
- To get started, edit src/App.js
and save to reload.
-
Rental #{this.state.currentRental.count}
+"{this.state.currentRental.movie}" checked out by Customer #{this.state.currentRental.customer}
+ {this.state.currentRental.count && } +Movie Successfully Checked-In!
+ } + +#{props.customer.id}. {props.customer.name}
+{selectButton}{rentalButton}
+ {props.viewCustomerRental && +Title | +Check-out | +Check-in | +
---|
Release Date: {props.movie.release_date}
+Overview: {props.movie.overview.length > 128 ? `${props.movie.overview.substring(0, 150)}...` : props.movie.overview}
+Release Date: {release_date}
+Overview: {overview}
+ +Release Date: {props.release_date}
+Overview: {props.overview}
+Inventory: {props.inventory}
+Available Inventory: {props.available_inventory}
+