diff --git a/app/package-lock.json b/app/package-lock.json
index c3e2785..7f11343 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -1184,6 +1184,16 @@
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
"integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw=="
},
+ "@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.15",
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.15.tgz",
+ "integrity": "sha512-rVNba1A2oMzKBg16fCrrHmCf4JjOzFhT9TWR8J+Y8iOcY4zffxtP3ke7mEsakvghHZT+9//uDOPSSeuBDW41GQ=="
+ },
"@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",
@@ -1362,11 +1372,25 @@
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz",
"integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A=="
},
+ "@types/prop-types": {
+ "version": "15.7.3",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
+ },
"@types/q": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
},
+ "@types/react": {
+ "version": "16.9.11",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.11.tgz",
+ "integrity": "sha512-UBT4GZ3PokTXSWmdgC/GeCGEJXE5ofWyibCcecRLUVN2ZBpXQGVgQGtG2foS7CrTKFKlQVVswLvf7Js6XA/CVQ==",
+ "requires": {
+ "@types/prop-types": "*",
+ "csstype": "^2.2.0"
+ }
+ },
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
@@ -2446,6 +2470,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",
@@ -3331,6 +3360,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",
@@ -3717,6 +3751,15 @@
"sha.js": "^2.4.8"
}
},
+ "create-react-context": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz",
+ "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==",
+ "requires": {
+ "gud": "^1.0.0",
+ "warning": "^4.0.3"
+ }
+ },
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -4006,6 +4049,11 @@
"cssom": "0.3.x"
}
},
+ "csstype": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz",
+ "integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ=="
+ },
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
@@ -4309,6 +4357,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.2.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
@@ -5921,9 +5977,9 @@
"integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ=="
},
"handlebars": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.0.tgz",
- "integrity": "sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw==",
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.5.tgz",
+ "integrity": "sha512-0Ce31oWVB7YidkaTq33ZxEbN+UDxMMgThvCe8ptgQViymL5DPis9uLdTA13MiRPhgvqyxIegugrP97iK3JeBHg==",
"requires": {
"neo-async": "^2.6.0",
"optimist": "^0.6.1",
@@ -7955,6 +8011,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",
@@ -9379,6 +9440,11 @@
"ts-pnp": "^1.1.2"
}
},
+ "popper.js": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz",
+ "integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw=="
+ },
"portfinder": {
"version": "1.0.24",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.24.tgz",
@@ -10320,6 +10386,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"
+ }
+ }
+ }
+ },
"proxy-addr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
@@ -10461,9 +10546,9 @@
}
},
"react": {
- "version": "16.9.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz",
- "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==",
+ "version": "16.11.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.11.0.tgz",
+ "integrity": "sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
@@ -10483,6 +10568,33 @@
"whatwg-fetch": "3.0.0"
}
},
+ "react-bootstrap": {
+ "version": "1.0.0-beta.14",
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.14.tgz",
+ "integrity": "sha512-UGK5f78FE8wAei1YL/oSwFlJZLqxJ/h4S8DCwHyY8hQjFCrjEW5PoEBTOOhQ6PQL6WOsZe1jkiOJG7L5TZWu+w==",
+ "requires": {
+ "@babel/runtime": "^7.4.2",
+ "@restart/context": "^2.1.4",
+ "@restart/hooks": "^0.3.11",
+ "@types/react": "^16.8.23",
+ "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-dev-utils": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-9.0.3.tgz",
@@ -10568,6 +10680,50 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
"integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw=="
},
+ "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-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.4",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.4.tgz",
+ "integrity": "sha512-9AcQB29V+WrBKk6X7p0eojd1f25/oJajVdMZkywIoAV6Ag7hzE1Mhyeup2Q1QnvFRtGQFQvtqfhlEoDAPfKAVA==",
+ "requires": {
+ "@babel/runtime": "^7.1.2",
+ "create-react-context": "^0.3.0",
+ "popper.js": "^1.14.4",
+ "prop-types": "^15.6.1",
+ "typed-styles": "^0.0.7",
+ "warning": "^4.0.2"
+ }
+ },
"react-router": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz",
@@ -10675,6 +10831,38 @@
"workbox-webpack-plugin": "4.3.1"
}
},
+ "react-transition-group": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz",
+ "integrity": "sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==",
+ "requires": {
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
+ "loose-envify": "^1.4.0",
+ "prop-types": "^15.6.2"
+ },
+ "dependencies": {
+ "dom-helpers": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz",
+ "integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==",
+ "requires": {
+ "@babel/runtime": "^7.6.3",
+ "csstype": "^2.6.7"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz",
+ "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==",
+ "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",
@@ -12515,6 +12703,11 @@
"mime-types": "~2.1.24"
}
},
+ "typed-styles": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
+ "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
+ },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -12541,6 +12734,16 @@
}
}
},
+ "uncontrollable": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.0.2.tgz",
+ "integrity": "sha512-7fa8OBQ5+X4VAcp0os6BD74bCeUPQSHmr4Rqy75Me98NnlD5kNShCqqx4xWo4OmlAMiT2/YSMklLFC4FCuoGYg==",
+ "requires": {
+ "@babel/runtime": "^7.4.5",
+ "invariant": "^2.2.4",
+ "react-lifecycles-compat": "^3.0.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",
@@ -12841,6 +13044,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/app/package.json b/app/package.json
index e1689a6..21ff778 100644
--- a/app/package.json
+++ b/app/package.json
@@ -3,7 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
- "react": "^16.9.0",
+ "bootstrap": "^4.3.1",
+ "react": "^16.11.0",
+ "react-bootstrap": "^1.0.0-beta.14",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
"react-scripts": "3.1.1",
diff --git a/app/src/components/App/index.jsx b/app/src/components/App/index.jsx
index 448f430..de7b68c 100644
--- a/app/src/components/App/index.jsx
+++ b/app/src/components/App/index.jsx
@@ -2,12 +2,14 @@ import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import Remote from 'components/Remote';
+import Student from 'components/Student';
export default class App extends React.Component {
render() {
return (
+
);
}
diff --git a/app/src/components/Student/index.jsx b/app/src/components/Student/index.jsx
new file mode 100644
index 0000000..c665e04
--- /dev/null
+++ b/app/src/components/Student/index.jsx
@@ -0,0 +1,69 @@
+import React from 'react';
+import { Container, Row, Col, Button } from 'react-bootstrap';
+
+export default class Student extends React.Component {
+ COURSE_1 = {
+ uuid: 1,
+ name: 'CS 125',
+ hasJoined: true
+ };
+ COURSE_2 = {
+ uuid: 2,
+ name: 'CS 126',
+ hasJoined: true
+ };
+ COURSE_3 = {
+ uuid: 3,
+ name: 'CS 173',
+ hasJoined: false
+ };
+ COURSE_4 = {
+ uuid: 4,
+ name: 'CS 225',
+ hasJoined: true
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ username: 'Tommy',
+ courses: [
+ this.COURSE_1,
+ this.COURSE_2,
+ this.COURSE_3,
+ this.COURSE_4
+ ]
+ };
+ }
+
+ render() {
+ const courseList = this.state.courses.map((course) =>
+
+
+ {course.name}
+
+
+
+
+
+ );
+
+ return (
+
+
+
+ {this.state.username}
+
+ {courseList}
+
+
+
+
+
+ );
+ }
+}
diff --git a/app/src/index.js b/app/src/index.js
index 2932928..8e848c0 100644
--- a/app/src/index.js
+++ b/app/src/index.js
@@ -3,5 +3,6 @@ import ReactDOM from 'react-dom';
import App from './components/App';
import './index.css';
+import 'bootstrap/dist/css/bootstrap.min.css';
ReactDOM.render(, document.getElementById('root'));