AppStateESS/InternshipInventory

View on GitHub
javascript/editCourses/courseEditor.jsx

Summary

Maintainability
D
1 day
Test Coverage
import React from 'react';
import ReactDOM from 'react-dom';

import $ from 'jquery';

/**
 * Notification component used for adding or delete courses.
 **/
class Notifications extends React.Component {
    render(){
        var notification;

        // Determine if the screen should render a notification.
        if (this.props.msg !== '') {
            if (this.props.msgType === 'success') {
                notification = <div className="alert alert-success" role="alert">
                                <i className="fa fa-check fa-2x pull-left"></i> {this.props.msg}
                            </div>
            } else if (this.props.msgType === 'error') {
                notification = <div className="alert alert-danger" role="alert">
                                    <i className="fa fa-times fa-2x pull-left"></i> {this.props.msg}
                               </div>
            }
        } else {
            notification = '';
        }

        return (
            <div>{notification}</div>
        );
    }
}

// Component creates a row for the courses
class CourseRow extends React.Component {
    constructor(props){
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }
    handleChange(e) {
        var name = this.props.abbr + " - " + this.props.name;
        this.props.deleteCourse(this.props.id, name, this.props.cnum);
    }
    render() {
        return (
            <tr>
                <td> {this.props.abbr} - {this.props.name} {this.props.cnum}</td>
                <td> <a onClick={this.handleChange}> <i className="fa fa-trash-o" /> </a> </td>
            </tr>
        );
    }
}

// Component helps create the table
class CourseList extends React.Component {
    render() {
        var deleteCourse = this.props.deleteCourse;
        // Determines if it needs to create a row.
        var cRow = null;
        if (this.props.subjectData != null){
            cRow = this.props.subjectData.map(function(sub) {
                return (
                    <CourseRow key={sub.id}
                               id={sub.id}
                               abbr={sub.abbreviation}
                               name={sub.description}
                               cnum={sub.course_num}
                               deleteCourse={deleteCourse} />
                );
            });
        } else{
            cRow = null;
        }

        return (
            <table className="table table-condensed table-striped">
                <thead>
                    <tr>
                        <th>Course</th>
                        <th>Delete</th>
                    </tr>
                </thead>
                <tbody>
                    {cRow}
                </tbody>
            </table>
        );
    }
}

// Component used to create a course
class CreateCourse extends React.Component {
    constructor(props) {
        super(props);

        this.state = {subject: "_-1"};

        this.handleDrop = this.handleDrop.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleKeyPress = this.handleKeyPress.bind(this);
    }
    handleDrop(e) {
        this.setState({subject: e.target.value});
    }
    handleSubmit(){
        // Trims the value and then determines if its length is = 4 and if it's all numbers.
        var courseNum = ReactDOM.findDOMNode(this.refs.courseNum).value.trim();
        if (courseNum.length === 4 && /^\d+$/.test(courseNum) && this.state.subject !== '_-1')
        {
            this.props.saveCourse(this.state.subject, courseNum);
        }
    }
  handleKeyPress (e) {
    // Making the Enter button on keyboard work for Create Course button.
    if (e.charCode === 13){
      this.handleSubmit();
      this.handleFocus();

    }
  }
  handleFocus() {
    //Select text field after Enter used.
    this.refs.courseNum.select();
  }
    render() {
        return (
            <div className="panel panel-default">
                <div className="panel-body">
                    <div className="row">
                        <div className="col-md-6">
                            <label>Subjects:</label>
                            <select className="form-control" onChange={this.handleDrop}>
                                {Object.keys(this.props.subjects).map(function(key) {
                                    return <option key={key} value={key}>{this.props.subjects[key]}</option>;
                                }.bind(this))}
                            </select>
                        </div>
                        <div className="col-md-6">
                            <label>Course Number:</label>
                            <input type="text" className="form-control" placeholder="0000" ref="courseNum" onKeyPress={this.handleKeyPress} />
                        </div>
                    </div>
                    <div className="row">
                        <br />
                        <div className="col-md-3 col-md-offset-6">
                            <button type="button" className="btn btn-default" onClick={this.handleSubmit} > Create Course </button>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

class CourseSelector extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            subjectData: null,
            msgNotification: '',
            msgType: ''
        };

        this.getCourseData = this.getCourseData.bind(this);
        this.saveCourse = this.saveCourse.bind(this);
        this.deleteCourse = this.deleteCourse.bind(this);
    }
    UNSAFE_componentWillMount(){
        this.getCourseData();
    }
    getCourseData(){
        $.ajax({
            url: 'index.php?module=intern&action=NormalCoursesRest',
            type: 'GET',
            dataType: 'json',
                success: function(data) {
                this.setState({subjectData: data});
            }.bind(this),
            error: function(xhr, status, err) {
                alert("Failed to grab subject data.")
                console.error(this.props.url, status, err.toString());
            }.bind(this)
        });
    }
    saveCourse(subjectId, course_num){
        $.ajax({
            url: 'index.php?module=intern&action=NormalCoursesRest&subjectId=' + subjectId + '&cnum=' + course_num,
            type: 'POST',
            success: function() {
                this.getCourseData();

                // Create success message.
                var msg = 'Successfully added ' + this.props.subjects[subjectId] + ' ' + course_num;
                this.setState({msgNotification:msg, msgType:'success'})
            }.bind(this),
            error: function(http) {
                // Create error message.
                var msg = 'Could not add ' + this.props.subjects[subjectId] + " " + course_num + " because ";
                this.setState({msgNotification:msg + http.responseText, msgType:'error'})
            }.bind(this)
        });
    }
    deleteCourse(id, name, course_num){
        $.ajax({
            url: 'index.php?module=intern&action=NormalCoursesRest&courseId='+id,
            type: 'DELETE',
            success: function() {
                this.getCourseData();

                // Create success message.
                var msg = 'Successfully deleted '+ name + " " + course_num;
                this.setState({msgNotification:msg, msgType:'success'})
            }.bind(this),
            error: function(http) {

                // Create error message.
                var msg = 'Could not delete ' + name + " " + course_num + " because ";
                this.setState({msgNotification:msg + http.responseText, msgType:'error'})
            }.bind(this)
        });
    }
    render() {
        return (
            <div>
                <Notifications msg={this.state.msgNotification} msgType={this.state.msgType} />

                <div className="row">
                    <div className="col-lg-5">
                        <CourseList    subjectData={this.state.subjectData} deleteCourse={this.deleteCourse} />
                    </div>

                    <div className="col-lg-5 col-lg-offset-1">
                        <CreateCourse subjects={this.props.subjects} saveCourse={this.saveCourse} />
                    </div>
                </div>
            </div>
        );
    }
}


ReactDOM.render(
    <CourseSelector subjects={window.subjects}/>,
    document.getElementById('edit_courses')
);