Skip to content

Commit

Permalink
Merge pull request #1 from abraha2d/dev
Browse files Browse the repository at this point in the history
Release v0.2.0-alpha.1
  • Loading branch information
abraha2d committed Aug 9, 2018
2 parents 361cbdd + 9c2976e commit b21c92c
Show file tree
Hide file tree
Showing 7 changed files with 415 additions and 88 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ yarn-debug.log*
yarn-error.log*

.idea/workspace.xml
.idea/dictionaries
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "coursewatch",
"version": "0.1.0",
"version": "0.2.0-alpha.1",
"homepage": "https://web.coursewatch.sueztech.com",
"bugs": "https://github.com/abraha2d/coursewatch/issues",
"license": "UNLICENSED",
Expand Down Expand Up @@ -33,6 +33,7 @@
"lodash": "^4.17.10",
"prop-types": "*",
"react": "^16.4.1",
"react-autosuggest": "^9.3.4",
"react-dom": "^16.4.1",
"react-helmet": "^5.2.0",
"react-redux": "^5.0.7",
Expand Down Expand Up @@ -78,5 +79,12 @@
"git add"
]
},
"proxy": "https://web.coursewatch.sueztech.com"
"proxy": {
"/api": {
"target": "http://localhost:9000",
"pathRewrite": {
"^/api/": "/"
}
}
}
}
195 changes: 170 additions & 25 deletions src/components/AddCourseDialog/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import React from "react";
import PropTypes from "prop-types";
import { compose } from "redux";
import axios from "axios";
import Autosuggest from "react-autosuggest";

import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
ListItemText,
MenuItem,
Paper,
TextField,
Typography,
Expand All @@ -38,41 +41,121 @@ const styles = theme => ({

class AddCourseDialog extends React.PureComponent {
state = {
term: "201809",
crn: "",
college: "",
term: "",
course: "",
loading: false,
responses: {
colleges: null,
terms: null,
courses: null
},
suggestions: [],
courseId: "",
error: null,
errors: {
college: false,
term: false,
crn: false
course: false
}
};

handleChange = name => event => {
const value = event.target.value;
handleChange = name => (event, nvm) => {
const value = nvm ? nvm.newValue : event.target.value;
this.setState(prevState => ({
[name]: value,
errors: {
...prevState.errors,
[name]: false
}
}));
if (name === "college") {
this.setState({ term: "", course: "", courseId: "" });
this.getTerms(value);
} else if (name === "term") {
this.setState({ course: "", courseId: "" });
this.getCourses(value);
}
};

getColleges = () => {
this.setState(prevState => ({
error: null,
loading: true,
responses: { ...prevState.responses, terms: null, courses: null },
suggestions: []
}));
return axios
.get("/api/colleges", {
headers: { Authorization: `Bearer ${this.props.apiAccessToken}` }
})
.then(response => {
this.setState(prevState => ({
loading: false,
responses: { ...prevState.responses, colleges: response.data }
}));
})
.catch(error => this.setState({ loading: false, error }));
};

getTerms = college => {
this.setState(prevState => ({
error: null,
loading: true,
responses: { ...prevState.responses, courses: null },
suggestions: []
}));
return axios
.get(`/api/terms?college=${college}`, {
headers: { Authorization: `Bearer ${this.props.apiAccessToken}` }
})
.then(response => {
this.setState(prevState => ({
loading: false,
responses: { ...prevState.responses, terms: response.data }
}));
})
.catch(error => this.setState({ loading: false, error }));
};

getCourses = term => {
this.setState({ error: null, loading: true });
return axios
.get(`/api/courses?term=${term}`, {
headers: { Authorization: `Bearer ${this.props.apiAccessToken}` }
})
.then(response => {
this.setState(prevState => ({
loading: false,
responses: { ...prevState.responses, courses: response.data }
}));
this.setState({ suggestions: this.getSuggestions(this.state.course) });
})
.catch(error => this.setState({ loading: false, error }));
};

// noinspection JSUnresolvedVariable
getCourseValue = course =>
`${course.crn} - ${course.subject} ${course.number} ${course.section}`;

getSuggestions = input =>
this.state.responses.courses.filter(course => {
return this.getCourseValue(course)
.toLowerCase()
.includes(input.toLowerCase());
});

addCourse = event => {
event.preventDefault();
if (this.state.courseId === "") {
return;
}
this.setState({ error: null, loading: true });
axios
.post(
"/api/subscriptions",
{
term: this.state.term,
crn: this.state.crn,
title: `Sample Course (CRN: ${this.state.crn})`
},
{
headers: { Authorization: `Bearer ${this.props.apiAccessToken}` }
}
{ course: this.state.courseId },
{ headers: { Authorization: `Bearer ${this.props.apiAccessToken}` } }
)
.then(response => {
this.setState({ loading: false });
Expand All @@ -81,6 +164,10 @@ class AddCourseDialog extends React.PureComponent {
.catch(error => this.setState({ loading: false, error }));
};

componentWillMount() {
this.getColleges();
}

render() {
const { classes } = this.props;
return (
Expand All @@ -102,25 +189,83 @@ class AddCourseDialog extends React.PureComponent {
<DialogTitle id="add-dialog-title">Add course</DialogTitle>
<DialogContent>
<TextField
id="term"
label="Term"
select
label="College"
required
fullWidth
margin="dense"
value={this.state.term}
onChange={this.handleChange("term")}
error={this.state.errors.term !== false}
/>
value={this.state.college}
onChange={this.handleChange("college")}
disabled={this.state.responses.colleges === null}
error={this.state.errors.college !== false}
>
{this.state.responses.colleges &&
this.state.responses.colleges.map(college => (
<MenuItem key={college.id} value={college.id}>
{college.name}
</MenuItem>
))}
</TextField>
<TextField
id="crn"
label="CRN"
select
label="Term"
required
autoFocus
fullWidth
margin="dense"
value={this.state.crn}
onChange={this.handleChange("crn")}
error={this.state.errors.crn !== false}
value={this.state.term}
onChange={this.handleChange("term")}
disabled={this.state.responses.terms === null}
error={this.state.errors.term !== false}
>
{this.state.responses.terms &&
this.state.responses.terms.map(term => (
<MenuItem key={term.id} value={term.id}>
{term.name}
</MenuItem>
))}
</TextField>
<Autosuggest
suggestions={this.state.suggestions}
onSuggestionsFetchRequested={({ value }) => {
this.setState({
suggestions: this.getSuggestions(value)
});
}}
onSuggestionsClearRequested={() => {}}
getSuggestionValue={this.getCourseValue}
renderSuggestion={(course, { query, isHighlighted }) => (
<MenuItem selected={isHighlighted}>
<ListItemText
primary={this.getCourseValue(course)}
secondary={course.title}
/>
</MenuItem>
)}
inputProps={{
value: this.state.course,
onChange: this.handleChange("course")
}}
onSuggestionSelected={(event, { suggestion }) => {
this.setState({ courseId: suggestion.id });
}}
alwaysRenderSuggestions
highlightFirstSuggestion
renderInputComponent={inputProps => {
const { value, onChange, ...rest } = inputProps;
return (
<TextField
label="Course"
required
fullWidth
margin="dense"
value={value}
onChange={onChange}
disabled={this.state.responses.courses === null}
error={this.state.errors.course !== false}
inputProps={rest}
/>
);
}}
/>
</DialogContent>
<DialogActions>
Expand Down
Loading

0 comments on commit b21c92c

Please sign in to comment.