diff --git a/client/package-lock.json b/client/package-lock.json
index 9804c64e..a1e1feaa 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -8,6 +8,7 @@
"name": "message-board",
"version": "0.1.0",
"dependencies": {
+ "@material-ui/core": "^4.11.3",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.7.1",
@@ -2095,6 +2096,150 @@
"node": ">= 10.14.2"
}
},
+ "node_modules/@material-ui/core": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz",
+ "integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==",
+ "dependencies": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/styles": "^4.11.3",
+ "@material-ui/system": "^4.11.3",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.11.2",
+ "@types/react-transition-group": "^4.2.0",
+ "clsx": "^1.0.4",
+ "hoist-non-react-statics": "^3.3.2",
+ "popper.js": "1.16.1-lts",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0 || ^17.0.0",
+ "react-transition-group": "^4.4.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/material-ui"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.6 || ^17.0.0",
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@material-ui/styles": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz",
+ "integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==",
+ "dependencies": {
+ "@babel/runtime": "^7.4.4",
+ "@emotion/hash": "^0.8.0",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.11.2",
+ "clsx": "^1.0.4",
+ "csstype": "^2.5.2",
+ "hoist-non-react-statics": "^3.3.2",
+ "jss": "^10.5.1",
+ "jss-plugin-camel-case": "^10.5.1",
+ "jss-plugin-default-unit": "^10.5.1",
+ "jss-plugin-global": "^10.5.1",
+ "jss-plugin-nested": "^10.5.1",
+ "jss-plugin-props-sort": "^10.5.1",
+ "jss-plugin-rule-value-function": "^10.5.1",
+ "jss-plugin-vendor-prefixer": "^10.5.1",
+ "prop-types": "^15.7.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/material-ui"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.6 || ^17.0.0",
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@material-ui/styles/node_modules/csstype": {
+ "version": "2.6.16",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
+ "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
+ },
+ "node_modules/@material-ui/system": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
+ "integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
+ "dependencies": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/utils": "^4.11.2",
+ "csstype": "^2.5.2",
+ "prop-types": "^15.7.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/material-ui"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.6 || ^17.0.0",
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@material-ui/system/node_modules/csstype": {
+ "version": "2.6.16",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
+ "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
+ },
+ "node_modules/@material-ui/types": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+ "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
+ "peerDependencies": {
+ "@types/react": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@material-ui/utils": {
+ "version": "4.11.2",
+ "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
+ "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
+ "dependencies": {
+ "@babel/runtime": "^7.4.4",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0 || ^17.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -2759,6 +2904,14 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-transition-group": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
@@ -5704,6 +5857,15 @@
"node": ">=8.0.0"
}
},
+ "node_modules/css-vendor": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.8.3",
+ "is-in-browser": "^1.0.2"
+ }
+ },
"node_modules/css-what": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
@@ -9434,6 +9596,11 @@
"node": ">=8.12.0"
}
},
+ "node_modules/hyphenate-style-name": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
+ "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
+ },
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -9595,6 +9762,14 @@
"node": ">=0.8.19"
}
},
+ "node_modules/indefinite-observable": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz",
+ "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==",
+ "dependencies": {
+ "symbol-observable": "1.2.0"
+ }
+ },
"node_modules/indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
@@ -9904,6 +10079,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-in-browser": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+ "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+ },
"node_modules/is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
@@ -11232,6 +11412,89 @@
"verror": "1.10.0"
}
},
+ "node_modules/jss": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz",
+ "integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "csstype": "^3.0.2",
+ "indefinite-observable": "^2.0.1",
+ "is-in-browser": "^1.1.3",
+ "tiny-warning": "^1.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/jss"
+ }
+ },
+ "node_modules/jss-plugin-camel-case": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz",
+ "integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "hyphenate-style-name": "^1.0.3",
+ "jss": "10.6.0"
+ }
+ },
+ "node_modules/jss-plugin-default-unit": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz",
+ "integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "node_modules/jss-plugin-global": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz",
+ "integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "node_modules/jss-plugin-nested": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz",
+ "integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "node_modules/jss-plugin-props-sort": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz",
+ "integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "node_modules/jss-plugin-rule-value-function": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz",
+ "integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "node_modules/jss-plugin-vendor-prefixer": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz",
+ "integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "css-vendor": "^2.0.8",
+ "jss": "10.6.0"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
@@ -13068,6 +13331,11 @@
"node": ">=6"
}
},
+ "node_modules/popper.js": {
+ "version": "1.16.1-lts",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+ "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+ },
"node_modules/portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
@@ -17745,6 +18013,14 @@
"node": ">=4"
}
},
+ "node_modules/symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -22427,6 +22703,89 @@
"chalk": "^4.0.0"
}
},
+ "@material-ui/core": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.3.tgz",
+ "integrity": "sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/styles": "^4.11.3",
+ "@material-ui/system": "^4.11.3",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.11.2",
+ "@types/react-transition-group": "^4.2.0",
+ "clsx": "^1.0.4",
+ "hoist-non-react-statics": "^3.3.2",
+ "popper.js": "1.16.1-lts",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0 || ^17.0.0",
+ "react-transition-group": "^4.4.0"
+ }
+ },
+ "@material-ui/styles": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.11.3.tgz",
+ "integrity": "sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@emotion/hash": "^0.8.0",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.11.2",
+ "clsx": "^1.0.4",
+ "csstype": "^2.5.2",
+ "hoist-non-react-statics": "^3.3.2",
+ "jss": "^10.5.1",
+ "jss-plugin-camel-case": "^10.5.1",
+ "jss-plugin-default-unit": "^10.5.1",
+ "jss-plugin-global": "^10.5.1",
+ "jss-plugin-nested": "^10.5.1",
+ "jss-plugin-props-sort": "^10.5.1",
+ "jss-plugin-rule-value-function": "^10.5.1",
+ "jss-plugin-vendor-prefixer": "^10.5.1",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "csstype": {
+ "version": "2.6.16",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
+ "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
+ }
+ }
+ },
+ "@material-ui/system": {
+ "version": "4.11.3",
+ "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.11.3.tgz",
+ "integrity": "sha512-SY7otguNGol41Mu2Sg6KbBP1ZRFIbFLHGK81y4KYbsV2yIcaEPOmsCK6zwWlp+2yTV3J/VwT6oSBARtGIVdXPw==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/utils": "^4.11.2",
+ "csstype": "^2.5.2",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "csstype": {
+ "version": "2.6.16",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
+ "integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
+ }
+ }
+ },
+ "@material-ui/types": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+ "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==",
+ "requires": {}
+ },
+ "@material-ui/utils": {
+ "version": "4.11.2",
+ "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.11.2.tgz",
+ "integrity": "sha512-Uul8w38u+PICe2Fg2pDKCaIG7kOyhowZ9vjiC1FsVwPABTW8vPPKfF6OvxRq3IiBaI1faOJmgdvMG7rMJARBhA==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "prop-types": "^15.7.2",
+ "react-is": "^16.8.0 || ^17.0.0"
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -22903,6 +23262,14 @@
"@types/react": "*"
}
},
+ "@types/react-transition-group": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
@@ -25271,6 +25638,15 @@
"source-map": "^0.6.1"
}
},
+ "css-vendor": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
+ "requires": {
+ "@babel/runtime": "^7.8.3",
+ "is-in-browser": "^1.0.2"
+ }
+ },
"css-what": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
@@ -28238,6 +28614,11 @@
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
},
+ "hyphenate-style-name": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
+ "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
+ },
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -28345,6 +28726,14 @@
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
},
+ "indefinite-observable": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/indefinite-observable/-/indefinite-observable-2.0.1.tgz",
+ "integrity": "sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==",
+ "requires": {
+ "symbol-observable": "1.2.0"
+ }
+ },
"indent-string": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
@@ -28564,6 +28953,11 @@
"is-extglob": "^2.1.1"
}
},
+ "is-in-browser": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+ "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+ },
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
@@ -29577,6 +29971,85 @@
"verror": "1.10.0"
}
},
+ "jss": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz",
+ "integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "csstype": "^3.0.2",
+ "indefinite-observable": "^2.0.1",
+ "is-in-browser": "^1.1.3",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-camel-case": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz",
+ "integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "hyphenate-style-name": "^1.0.3",
+ "jss": "10.6.0"
+ }
+ },
+ "jss-plugin-default-unit": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz",
+ "integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "jss-plugin-global": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz",
+ "integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "jss-plugin-nested": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz",
+ "integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-props-sort": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz",
+ "integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0"
+ }
+ },
+ "jss-plugin-rule-value-function": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz",
+ "integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "jss": "10.6.0",
+ "tiny-warning": "^1.0.2"
+ }
+ },
+ "jss-plugin-vendor-prefixer": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz",
+ "integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "css-vendor": "^2.0.8",
+ "jss": "10.6.0"
+ }
+ },
"jsx-ast-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz",
@@ -31027,6 +31500,11 @@
"ts-pnp": "^1.1.6"
}
},
+ "popper.js": {
+ "version": "1.16.1-lts",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+ "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+ },
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
@@ -34793,6 +35271,11 @@
}
}
},
+ "symbol-observable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
+ },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
diff --git a/client/package.json b/client/package.json
index 3b2fa400..cf1f42b4 100644
--- a/client/package.json
+++ b/client/package.json
@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
+ "@material-ui/core": "^4.11.3",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.7.1",
diff --git a/client/src/App.js b/client/src/App.js
index df04b275..bad95f34 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -10,6 +10,7 @@ import ClassView from "./components/posts/ClassView";
import CommentView from "./components/comments/CommentView";
import { UserProvider } from "./components/context/UserProvider";
import PrivateRoute from "./PrivateRoute";
+import ConfigView from "./components/configPage/ConfigView";
function App() {
return (
@@ -47,6 +48,11 @@ function App() {
+
+
+
+
+
diff --git a/client/src/components/common/Button.js b/client/src/components/common/Button.js
index 49461d62..ddea2d19 100644
--- a/client/src/components/common/Button.js
+++ b/client/src/components/common/Button.js
@@ -7,7 +7,7 @@ import LoadingDots from "./animation/LoadingDots";
* The one true button to rule them all
*
* @version 1.0.0
- * @author [Alec Springel](https://github.com/alecspringel)
+ * @author [Alec Springel](https://github.com/alecspringel) , [Seth Tal](https://github.com/Sephta)
*/
const Button = ({ children, loading, onClick, ...props }) => {
const clickHandler = loading ? undefined : onClick;
@@ -38,11 +38,14 @@ const Btn = styled.button`
border-radius: 3px;
font-size: 16px;
- width: ${(props) => props.autoWidth && "100%"};
+ width: ${(props) => (props.autoWidth ? "100%" : props.buttonWidth)};
+ height: ${(props) => (props.buttonHeight ? props.buttonHeight : "")};
display: flex;
justify-content: center;
align-items: center;
+ transition: ease-in-out 100ms;
+
// If secondary prop === true
${(props) =>
props.secondary &&
@@ -55,6 +58,25 @@ const Btn = styled.button`
background-color: #dedede;
}
`}
+ ${(props) =>
+ props.outlineSecondary &&
+ css`
+ border: 2px solid #4a86fa;
+ border-radius: 4px;
+ padding: 5px 12px;
+ background-color: #e7e7e700;
+ color: #162b55;
+ &:hover {
+ transform: ${(props) =>
+ props.animatedHover ? css`translateY(-0.5px);` : ""};
+ box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
+ }
+ &:active {
+ transform: ${(props) =>
+ props.animatedHover ? css`translateY(1px);` : ""};
+ box-shadow: 2px 2px 6px rgba(0, 0, 0, 0);
+ }
+ `}
// If largeSecondary prop === true
${(props) =>
@@ -71,10 +93,20 @@ const Btn = styled.button`
${(props) =>
props.primary &&
css`
- background-color: #4a86fa;
+ background-color: ${(props) =>
+ props.buttonColor ? props.buttonColor : css`#4a86fa`};
color: #fff;
&:hover {
- background-color: #407df3;
+ background-color: ${(props) =>
+ props.buttonColor ? props.buttonColor : css`#407df3`};
+ transform: ${(props) =>
+ props.animatedHover ? css`translateY(-0.5px);` : ""};
+ box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
+ }
+ &:active {
+ transform: ${(props) =>
+ props.animatedHover ? css`translateY(1px);` : ""};
+ box-shadow: 2px 2px 6px rgba(0, 0, 0, 0);
}
`}
@@ -90,4 +122,9 @@ const Btn = styled.button`
opacity: 0.85;
color: black;
`}
+ ${(props) =>
+ props.enableMargin &&
+ css`
+ margin: ${props.enableMargin};
+ `}
`;
diff --git a/client/src/components/common/css/noTextSelection.css b/client/src/components/common/css/noTextSelection.css
new file mode 100644
index 00000000..f6d2b3a7
--- /dev/null
+++ b/client/src/components/common/css/noTextSelection.css
@@ -0,0 +1,11 @@
+/* https://stackoverflow.com/questions/826782/how-to-disable-text-selection-highlighting */
+/* Pass this to the className prop to disable text selection on that component */
+.noselect {
+ -webkit-touch-callout: none; /* iOS Safari */
+ -webkit-user-select: none; /* Safari */
+ -khtml-user-select: none; /* Konqueror HTML */
+ -moz-user-select: none; /* Old versions of Firefox */
+ -ms-user-select: none; /* Internet Explorer/Edge */
+ user-select: none; /* Non-prefixed version, currently
+ supported by Chrome, Edge, Opera and Firefox */
+}
diff --git a/client/src/components/configPage/ConfigButtonPanel.js b/client/src/components/configPage/ConfigButtonPanel.js
new file mode 100644
index 00000000..f9c23c44
--- /dev/null
+++ b/client/src/components/configPage/ConfigButtonPanel.js
@@ -0,0 +1,54 @@
+import React from "react";
+import styled from "styled-components";
+import PropTypes from "prop-types";
+import Button from "../common/Button";
+import "../common/css/noTextSelection.css";
+
+/**
+ *
+ * @param {string} panelText the text description of the panel...
+ * @returns
+ */
+const ConfigButtonPanel = ({ panelText, ...props }) => {
+ return (
+
+ {panelText}
+ {props.children}
+
+ );
+};
+
+export default ConfigButtonPanel;
+
+// ConfigButtonPanel.PropTypes = {};
+
+const ConfigPanelWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ max-width: 900px;
+ margin: 1em 0;
+ padding: 0.5em;
+ box-shadow: 0px 1px 4px 2px rgba(0, 0, 0, 0.07);
+ border-radius: 5px;
+
+ /* border: 1px solid black; */
+ /* border-radius: 0.25em; */
+`;
+
+const ConfigTextWrapper = styled.div`
+ color: #737373;
+
+ margin: 0 2rem;
+
+ /* border: 1px solid orange; */
+ border-radius: 0.25em;
+`;
+
+const ConfigChildrenWrapper = styled.div`
+ flex-shrink: 0;
+ margin: 0 2rem;
+
+ /* border: 1px solid blue; */
+`;
diff --git a/client/src/components/configPage/ConfigView.js b/client/src/components/configPage/ConfigView.js
new file mode 100644
index 00000000..9ce01bd2
--- /dev/null
+++ b/client/src/components/configPage/ConfigView.js
@@ -0,0 +1,91 @@
+import React from "react";
+import styled, { css } from "styled-components";
+import ConfigPanel from "./ConfigButtonPanel";
+import Button from "../common/Button";
+import LazyFetch from "../common/requests/LazyFetch";
+
+const ConfigView = ({ props }) => {
+ return (
+
+
+ THIS IS THE CONFIG PAGE
+
+
+
+
+
+
+
+
+
+ {/* KEEP THE OVERFLOW COUNTER IT HELPS WITH OVERFLOW
+ at the bottom of the scrolling div. */}
+
+
+
+ );
+};
+
+export default ConfigView;
+
+const ConfigWrapper = styled.div`
+ width: 100%;
+ min-height: 100vh;
+ position: relative;
+`;
+
+const ScrollingDiv = styled.div`
+ position: absolute;
+ height: 100%;
+ width: 100%;
+ padding: 2rem 4rem 0 4rem;
+
+ overflow: auto;
+`;
+
+/** THIS ACCOUNTS FOR WEIRD SCROLLING DIV STUFF */
+const OverflowCounter = styled.div`
+ width: 100%;
+ ${(props) =>
+ props.offsetAmount &&
+ css`
+ padding: ${props.offsetAmount};
+ `}
+`;
diff --git a/client/src/components/navigation/NavigationWrapper.js b/client/src/components/navigation/NavigationWrapper.js
index 8668ff68..7678077c 100644
--- a/client/src/components/navigation/NavigationWrapper.js
+++ b/client/src/components/navigation/NavigationWrapper.js
@@ -7,7 +7,6 @@ import TopNavBar from "./TopNavBar";
* @brief DEPRECATED ~ but will consider refactoring some webpages to incorporate.
* @param {idk?} children container of child components.
* @returns
- * @deprecated This component is unused and has since been deprecated.
*/
const MenuMargin = ({ children }) => {
return (
diff --git a/client/src/components/posts/Options.js b/client/src/components/posts/Options.js
index b3633b46..49da513f 100644
--- a/client/src/components/posts/Options.js
+++ b/client/src/components/posts/Options.js
@@ -1,8 +1,10 @@
-import React from "react";
+import React, { useContext } from "react";
+import { UserContext } from "../context/UserProvider";
import PropTypes from "prop-types";
import styled from "styled-components";
import Button from "../common/Button";
import { Link } from "react-router-dom";
+import CogIcon from "../../imgs/settings 1.svg";
/**
* Options Component ~ Button side panel for displaying buttons for the user
@@ -10,18 +12,77 @@ import { Link } from "react-router-dom";
* @param {string} courseId given to the "+ New Post" button to route to the Post form page
*/
const Options = ({ courseId }) => {
+ const user = useContext(UserContext);
+ console.log("User Object: ", user);
+
+ // Will be used to conditionally render the config page button
+ var userIsAdmin = false;
+
+ // Checks the current user course for Admin privledge status
+ // sets the above 'userIsAdmin' variable accordingly
+ for (let i = 0; i < user.courses.length; i++) {
+ if (user?.courses[i].courseId == courseId) {
+ userIsAdmin = user.courses[i].admin;
+ }
+ }
+
+ // console.log(userIsAdmin);
+
return (
OPTIONS
-
);
diff --git a/client/src/components/posts/PostView.js b/client/src/components/posts/PostView.js
index 8473800b..27ba4533 100644
--- a/client/src/components/posts/PostView.js
+++ b/client/src/components/posts/PostView.js
@@ -98,6 +98,7 @@ const PostView = ({ highlightedSection }) => {
secondary={true}
onClick={() => {
setCondensedState(!isCondensed);
+ alert("This feature is a work in progress.");
}}
>
diff --git a/client/src/imgs/settings 1.svg b/client/src/imgs/settings 1.svg
new file mode 100644
index 00000000..da73659f
--- /dev/null
+++ b/client/src/imgs/settings 1.svg
@@ -0,0 +1,13 @@
+