diff --git a/client/package-lock.json b/client/package-lock.json index 073d3e0..8474a02 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "utd-grades-client", - "version": "1.0.0", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3658,8 +3658,7 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { "version": "1.0.1", @@ -8532,6 +8531,24 @@ "prepend-http": "1.0.4", "query-string": "4.3.4", "sort-keys": "1.1.2" + }, + "dependencies": { + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "strict-uri-encode": "1.1.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + } } }, "npm-install-webpack2-plugin": { @@ -11584,13 +11601,12 @@ "dev": true }, "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.2.0.tgz", + "integrity": "sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA==", "requires": { - "object-assign": "4.1.1", - "strict-uri-encode": "1.1.0" + "decode-uri-component": "0.2.0", + "strict-uri-encode": "2.0.0" } }, "querystring": { @@ -12297,6 +12313,15 @@ "warning": "4.0.2" } }, + "react-scroll": { + "version": "1.7.10", + "resolved": "https://registry.npmjs.org/react-scroll/-/react-scroll-1.7.10.tgz", + "integrity": "sha512-7K1caXF19PQ/jck+QRCdRMytqWei1ktv7jtcsgMap2s55pGOUc/a5phr4loajZRFRx3qKj9Tz12KDtELp91xMg==", + "requires": { + "lodash.throttle": "4.1.1", + "prop-types": "15.6.2" + } + }, "react-slick": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.23.1.tgz", @@ -13961,10 +13986,9 @@ } }, "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" }, "string-convert": { "version": "0.2.1", diff --git a/client/package.json b/client/package.json index bda83aa..3e7d1c8 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "utd-grades-client", - "version": "0.1.0", + "version": "0.2.0", "scripts": { "build": "nwb build-react-app", "clean": "nwb clean-app", @@ -14,10 +14,12 @@ "chart.js": "^2.7.2", "isomorphic-fetch": "^2.2.1", "lodash": "^4.17.10", + "query-string": "^6.2.0", "react": "^16.4.1", "react-dom": "^16.4.1", "react-redux": "^5.0.7", "react-router-dom": "^4.3.1", + "react-scroll": "^1.7.10", "react-transition-group": "^2.5.0", "redux": "^4.0.0", "redux-actions": "^2.6.1", diff --git a/client/public/bg.jpg b/client/public/bg.jpg deleted file mode 100644 index 4d630a4..0000000 Binary files a/client/public/bg.jpg and /dev/null differ diff --git a/client/src/components/Core/styles.scss b/client/src/components/Core/styles.scss index 8f38720..5972790 100644 --- a/client/src/components/Core/styles.scss +++ b/client/src/components/Core/styles.scss @@ -5,7 +5,9 @@ width: 100%; display: block; height: 60px; - font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif + font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; + padding-left: 10px; + padding-right: 10px; } .body { diff --git a/client/src/routes/Home/components/Form/index.js b/client/src/components/Form/index.js similarity index 68% rename from client/src/routes/Home/components/Form/index.js rename to client/src/components/Form/index.js index cd37b1f..e7631fa 100644 --- a/client/src/routes/Home/components/Form/index.js +++ b/client/src/components/Form/index.js @@ -1,23 +1,25 @@ import React from 'react'; import classes from './styles.scss'; import { Field, reduxForm } from 'redux-form'; -import { Form, Popover } from 'antd'; +import { Form, Popover, Input } from 'antd'; import { AutoComplete } from 'components/'; +const Search = Input.Search; + const renderField = ({ input, ...props }) => ( - + ); class HomeForm extends React.Component { render() { - const { handleSubmit, sections, onSearch, pristine, reset, submitting, onSelect } = this.props; + const { handleSubmit, onSearch, pristine, reset, submitting } = this.props; const content = (

You can search for:

  • A specific section: CS 1337.501
  • A whole course: CS 1337
  • -
  • A professor's name (first or last or both): Jason Smith
  • +
  • A professor's name (last name or full): Jason Smith
  • A specific semester: CS 1337 fall 2017
  • Everything together: CS 1337.1 fall 2017 jason smith
@@ -26,8 +28,8 @@ class HomeForm extends React.Component { return (
- + Need to know what you can enter? Pretty much anything. @@ -40,4 +42,5 @@ class HomeForm extends React.Component { export default reduxForm({ form: 'homeForm', + destroyOnUnmount: false, })(HomeForm); diff --git a/client/src/components/Form/styles.scss b/client/src/components/Form/styles.scss new file mode 100644 index 0000000..1573257 --- /dev/null +++ b/client/src/components/Form/styles.scss @@ -0,0 +1,15 @@ +.input input { + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1) !important; + border-radius: 20px !important; + outline: none; + font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; +} + +.hint { + margin-top: 25px; + margin-left: auto; + margin-right: auto; + display: block; + font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; + color: #95989A; +} diff --git a/client/src/components/index.js b/client/src/components/index.js index 1689c0e..876e0fc 100644 --- a/client/src/components/index.js +++ b/client/src/components/index.js @@ -1,9 +1,11 @@ import AutoComplete from './AutoComplete'; import Core from './Core'; import Graph from './Graph'; +import Form from './Form'; export { AutoComplete, Core, Graph, + Form, }; diff --git a/client/src/index.html b/client/src/index.html index 4670967..85609bb 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -5,7 +5,7 @@ UTD Grades - + diff --git a/client/src/modules/section/sagas.js b/client/src/modules/section/sagas.js index 28309be..06e5b00 100644 --- a/client/src/modules/section/sagas.js +++ b/client/src/modules/section/sagas.js @@ -11,8 +11,6 @@ export function* fetchSections(action) { }; try { - yield call(delay, 2000); - const response = yield call(data.request.bind(data), 'section', 'get', null, params); yield put(actions.receiveSections(response)); diff --git a/client/src/routes/Home/View.js b/client/src/routes/Home/View.js index 54a25be..5f49341 100644 --- a/client/src/routes/Home/View.js +++ b/client/src/routes/Home/View.js @@ -1,8 +1,10 @@ import React from 'react'; import classes from './styles.scss'; -import { Form, LinkCard } from './components'; -import { Core } from 'components/'; +import { LinkCard } from './components'; +import { Core, Form } from 'components/'; import { Row, Col, Card, Icon, Popover, Spin } from 'antd'; +import queryUtils from 'utils/query'; +import query from '../../utils/query'; export default class HomeView extends React.Component { state = { @@ -13,28 +15,24 @@ export default class HomeView extends React.Component { { name: 'Coursebook', backgroundColor: '#69BE28', link: 'https://coursebook.utdallas.edu' }, ], }; - handleSelect = (value, option) => { - //this.props.actions.submit('homeForm'); - this.props.history.push(`/app/section/${value}`); - }; - handleSearch = (search) => { - this.props.actions.fetchSections(search); + handleSearch = () => { + this.props.actions.submit('homeForm'); }; handleSubmit = (values) => { - this.props.history.push(`/app/section/${values.id}`); + queryUtils.pushQueryParamsToURL(this.props.location, this.props.history, { + search: values.search + }, '/app/results'); }; render() { - const antIcon = ; - return (
-

UTD Grades

+

UTD Grades

See how students did in any given class. And it's free, forever.

- +
diff --git a/client/src/routes/Home/components/Form/styles.scss b/client/src/routes/Home/components/Form/styles.scss deleted file mode 100644 index 5c7272a..0000000 --- a/client/src/routes/Home/components/Form/styles.scss +++ /dev/null @@ -1,17 +0,0 @@ -.input input { - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.46) !important; - border-radius: 20px !important; - outline: none; - border-top: none; - border-left: none; - border-right: none; -} - -.hint { - margin-top: 25px; - margin-left: auto; - margin-right: auto; - display: block; - font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; - color: #95989A; -} diff --git a/client/src/routes/Home/components/index.js b/client/src/routes/Home/components/index.js index fab37cc..f27c162 100644 --- a/client/src/routes/Home/components/index.js +++ b/client/src/routes/Home/components/index.js @@ -1,7 +1,5 @@ -import Form from './Form'; import LinkCard from './LinkCard'; export { - Form, LinkCard, }; diff --git a/client/src/routes/Home/index.js b/client/src/routes/Home/index.js index 7edac38..1ff7ccc 100644 --- a/client/src/routes/Home/index.js +++ b/client/src/routes/Home/index.js @@ -12,8 +12,6 @@ import { normalizedSectionsSelector } from 'modules/section/selectors'; const mapStateToProps = (state, ownProps) => ({ location: ownProps.location, history: ownProps.history, - sections: normalizedSectionsSelector(state), - loading: state.section.fetchSections.requesting, }); const actionCreators = { diff --git a/client/src/routes/Results/View.js b/client/src/routes/Results/View.js new file mode 100644 index 0000000..9c98b57 --- /dev/null +++ b/client/src/routes/Results/View.js @@ -0,0 +1,131 @@ +import React from 'react'; +import classes from './styles.scss'; +import { Core, Form } from 'components/'; +import { Content, List } from './components'; +import { Button, Row, Col, Card, Icon, Popover, Spin, Input } from 'antd'; +import queryUtils from 'utils/query'; +import { Element, scroller, animateScroll as scroll } from 'react-scroll'; + +export default class SectionView extends React.Component { + constructor(props) { + super(props); + + this.graphRef = React.createRef(); + } + componentDidMount() { + this.props.actions.resetSections(); + this.props.actions.resetSection(); + + this.init(); + } + componentDidUpdate(prevProps) { + this.init(prevProps); + } + init = (prevProps) => { + if (!prevProps) { + prevProps = {}; + } + + if (this.props.search) { + if (this.props.search !== prevProps.search) { + this.props.actions.resetSections(); + this.resetSection(); + + this.props.actions.fetchSections(this.props.search); + } + } + + if (this.props.sectionId) { + if (this.props.sectionId !== prevProps.sectionId) { + this.props.actions.resetOtherSections(); + + this.props.actions.fetchSection(this.props.sectionId); + } + } + + if (this.props.section && !prevProps.section) { + this.props.actions.fetchOtherSections({ + number: this.props.section.course.number, + prefix: this.props.section.course.prefix, + }); + } + }; + resetSection = () => { + this.props.actions.resetSection(); + + queryUtils.deleteQueryParam(this.props.location, this.props.history, 'section'); + }; + goHome = () => { + this.props.history.push('/'); + }; + handleSearch = () => { + this.props.actions.submit('homeForm'); + }; + handleSubmit = (values) => { + queryUtils.pushQueryParams(this.props.location, this.props.history, { + search: values.search, + }); + }; + handleClick = (id) => { + queryUtils.pushQueryParams(this.props.location, this.props.history, { + section: id, + }); + + scroll.scrollTo(this.graphRef.current.offsetTop); + }; + render() { + const content = () => { + if (this.props.section) { + return ; + } else if (this.props.requestingSection) { + return( +
+ +
+ ); + } else { + return ( +
+

Nothing to see here, select a section!

+
+ ); + } + }; + + return ( + + +