├── .DS_Store ├── backend ├── .DS_Store ├── profile_uploads │ └── .DS_Store ├── model │ ├── message.js │ ├── course_lectures.js │ ├── course_announce.js │ ├── course_assignment.js │ ├── course_grades.js │ ├── user_assignments.js │ ├── student_course.js │ ├── course_quiz.js │ ├── course.js │ └── user.js ├── kafka │ ├── client.js │ ├── connection.js │ └── kafkarpc.js ├── package.json ├── test.js └── index.js ├── frontend ├── .DS_Store ├── src │ ├── .DS_Store │ ├── components │ │ ├── CMPE273Lab1.pdf │ │ ├── style.css │ │ ├── Content.js │ │ ├── Template.js │ │ ├── SideMenu │ │ │ ├── DrawerToggle.css │ │ │ ├── DrawerToggle.jsx │ │ │ ├── SideMenu.css │ │ │ └── index.jsx │ │ ├── FileInput.js │ │ ├── MenuItem.js │ │ ├── ListBody.jsx │ │ ├── Home.js │ │ ├── Quiz │ │ │ ├── Question.js │ │ │ └── Quiz.js │ │ ├── ListItem.jsx │ │ ├── testcourse.css │ │ ├── Pagination.js │ │ ├── Announce.js │ │ ├── ViewSub.js │ │ ├── ToggleMenu.js │ │ ├── UpdatePhoto.js │ │ ├── Header.js │ │ ├── GradeAssignment.js │ │ ├── GradeEntry.js │ │ ├── Main.js │ │ ├── myfunctions.js │ │ ├── Inbox │ │ │ ├── Inbox.js │ │ │ ├── NewMessage.js │ │ │ └── Messages.js │ │ ├── SubmissionViewer.js │ │ ├── Signup.js │ │ ├── GenCode.js │ │ ├── Signin.js │ │ ├── SideBar.js │ │ ├── Assignment.js │ │ ├── Signin_ori.js │ │ └── DispProfile.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── reducers │ │ ├── reducer_newMsg.js │ │ ├── reducer_signUp.js │ │ ├── reducer_signin.js │ │ ├── reducer_updateProfile.js │ │ ├── reducer_dispProfile.js │ │ ├── reducer_createCourse.js │ │ └── index.js │ ├── store.js │ ├── App.js │ ├── actions │ │ ├── msgActions.js │ │ ├── courseActions.js │ │ └── userActions.js │ ├── logo.svg │ ├── App.css │ └── serviceWorker.js ├── public │ ├── favicon.ico │ ├── manifest.json │ ├── index.html │ └── js │ │ └── jquery.slimscroll.min.js ├── package.json └── README.md ├── kafka-backend ├── .DS_Store ├── services │ ├── .DS_Store │ ├── msgBySubject.js │ ├── getQuizById.js │ ├── getLectures.js │ ├── subassigns.js │ ├── getAssignmentById.js │ ├── getAssignments.js │ ├── getAnnouncements.js │ ├── replytomsg.js │ ├── announcement.js │ ├── addcourse.js │ ├── removestudent.js │ ├── assignment.js │ ├── profilepic.js │ ├── checkusercourse.js │ ├── updateprofile.js │ ├── sample_signin.js │ ├── get_courses.js │ ├── messagelist.js │ ├── profile.js │ ├── signin.js │ ├── signup.js │ └── coursedetails.js ├── model │ ├── message.js │ ├── dbconn.js │ ├── course_lectures.js │ ├── course_announce.js │ ├── course_assignment.js │ ├── course_grades.js │ ├── student_course.js │ ├── user_assignments.js │ ├── course_quiz.js │ ├── course.js │ └── user.js ├── package.json ├── kafka │ └── Connection.js └── server.js └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/.DS_Store -------------------------------------------------------------------------------- /backend/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/backend/.DS_Store -------------------------------------------------------------------------------- /frontend/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/frontend/.DS_Store -------------------------------------------------------------------------------- /frontend/src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/frontend/src/.DS_Store -------------------------------------------------------------------------------- /kafka-backend/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/kafka-backend/.DS_Store -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /backend/profile_uploads/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/backend/profile_uploads/.DS_Store -------------------------------------------------------------------------------- /kafka-backend/services/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/kafka-backend/services/.DS_Store -------------------------------------------------------------------------------- /frontend/src/components/CMPE273Lab1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rakheegit/Canvas_LMS/HEAD/frontend/src/components/CMPE273Lab1.pdf -------------------------------------------------------------------------------- /frontend/src/components/style.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | #page-numbers { 4 | list-style: none; 5 | display: flex; 6 | } 7 | 8 | #page-numbers > li { 9 | margin-right: 0.3em; 10 | color: rgb(60, 74, 158); 11 | user-select: none; 12 | cursor: pointer; 13 | } 14 | -------------------------------------------------------------------------------- /frontend/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/src/components/Content.js: -------------------------------------------------------------------------------- 1 | // Content.js 2 | 3 | import React, {Component} from 'react'; 4 | //import Search from './Search' 5 | 6 | 7 | export default class Content extends Component { 8 | render(){ 9 | return ( 10 |
11 | 12 |
13 | ) 14 | } 15 | } -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /backend/model/message.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var messageSchema = mongoose.Schema({ 3 | user_email: { 4 | type: String 5 | }, 6 | to_email: { 7 | type: String 8 | }, 9 | subject: { 10 | type: String 11 | }, 12 | message: { 13 | type: String 14 | } 15 | 16 | }) 17 | module.exports = mongoose.model('messages',messageSchema); -------------------------------------------------------------------------------- /frontend/src/components/Template.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | //import Search from './Search' 3 | 4 | 5 | export default class Template extends Component { 6 | render(){ 7 | console.log("this.props.targetId: " + this.props.targetId ) 8 | return ( 9 |
Helloooo 10 | {this.props.targetId} 11 |
12 | ) 13 | } 14 | } -------------------------------------------------------------------------------- /kafka-backend/model/message.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | var messageSchema = mongoose.Schema({ 4 | user_email: { 5 | type: String 6 | }, 7 | to_email: { 8 | type: String 9 | }, 10 | subject: { 11 | type: String 12 | }, 13 | message: { 14 | type: String 15 | } 16 | 17 | }) 18 | Message = module.exports = mongoose.model('messages',messageSchema); 19 | -------------------------------------------------------------------------------- /kafka-backend/model/dbconn.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | var uri = "mongodb+srv://canvas_user:2407Rakhee%21@cluster0-jjkgt.mongodb.net/canvasdb?poolSize=10?retryWrites=true" 4 | // var uri = "mongodb+srv://canvas_user:2407Rakhee%21@cluster0-jjkgt.mongodb.net/canvasdb?retryWrites=true" 5 | 6 | 7 | mongoose.connect(uri.toString()).then(() => console.log('connected to DB')) 8 | .catch(err => console.log("DB CONNECTION ERROR" + err)); -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /backend/model/course_lectures.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var lectureSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String 5 | }, 6 | 7 | user_file: { 8 | type: String 9 | }, 10 | posted_on: { 11 | type: String 12 | } 13 | 14 | }) 15 | const Lectures = module.exports = mongoose.model('course_lectures',lectureSchema); 16 | 17 | module.exports = Lectures; 18 | -------------------------------------------------------------------------------- /backend/model/course_announce.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var announceSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String, 5 | primaryKey: true 6 | }, 7 | title: { 8 | type: String 9 | }, 10 | posted_on: { 11 | type: String 12 | }, 13 | content: { 14 | type: String 15 | } 16 | }) 17 | module.exports = mongoose.model('announces',announceSchema); -------------------------------------------------------------------------------- /kafka-backend/model/course_lectures.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var lectureSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String 5 | }, 6 | 7 | user_file: { 8 | type: String 9 | }, 10 | posted_on: { 11 | type: String 12 | } 13 | 14 | }) 15 | const Lectures = module.exports = mongoose.model('course_lectures',lectureSchema); 16 | 17 | module.exports = Lectures; 18 | -------------------------------------------------------------------------------- /backend/kafka/client.js: -------------------------------------------------------------------------------- 1 | var rpc = new (require('./kafkarpc'))(); 2 | 3 | //make request to kafka 4 | function make_request(queue_name, msg_payload, callback){ 5 | console.log('in make request'); 6 | console.log(msg_payload); 7 | rpc.makeRequest(queue_name, msg_payload, function(err, response){ 8 | 9 | if(err) 10 | console.error(err); 11 | else{ 12 | console.log("response", response); 13 | callback(null, response); 14 | } 15 | }); 16 | } 17 | 18 | exports.make_request = make_request; -------------------------------------------------------------------------------- /frontend/src/components/SideMenu/DrawerToggle.css: -------------------------------------------------------------------------------- 1 | .toggle-button { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: space-around; 5 | height: 24px; 6 | width: 30px; 7 | background: transparent; 8 | border: none; 9 | cursor: pointer; 10 | padding: 0; 11 | box-sizing: border-box; 12 | margin-right: 10px; 13 | } 14 | 15 | .toggle-button:focus { 16 | outline: none; 17 | } 18 | 19 | .toggle-button-line { 20 | width: 30px; 21 | height: 2px; 22 | background: white; 23 | } 24 | -------------------------------------------------------------------------------- /frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | //import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /frontend/src/components/SideMenu/DrawerToggle.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import './DrawerToggle.css'; 5 | 6 | const DrawerToggle = (props) => { 7 | const { onDrawerToggleClick } = props; 8 | 9 | return ( 10 | 13 | ); 14 | }; 15 | 16 | DrawerToggle.propTypes = { 17 | onDrawerToggleClick: PropTypes.func.isRequired, 18 | }; 19 | 20 | export default DrawerToggle; 21 | -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_newMsg.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import {WRITE_MSG} from "../actions/msgActions"; 3 | 4 | 5 | //Reducer listening to different action types 6 | //initial state is {} 7 | export default function(state = {}, action) { 8 | switch (action.type) { 9 | //target 10 | 11 | case WRITE_MSG: 12 | console.log("new msg status " + action.payload) 13 | return { 14 | newmsg_status: action.payload 15 | } 16 | 17 | default: 18 | return state; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_signUp.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { SIGN_UP} from "../actions/userActions"; 3 | 4 | 5 | //Reducer listening to different action types 6 | //initial state is {} 7 | export default function(state = {}, action) { 8 | switch (action.type) { 9 | //target 10 | 11 | case SIGN_UP: 12 | console.log("signup status " + action.payload) 13 | return { 14 | signup_status: action.payload 15 | } 16 | 17 | default: 18 | return state; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_signin.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { SIGN_IN} from "../actions/userActions"; 3 | 4 | 5 | //Reducer listening to different action types 6 | //initial state is {} 7 | export default function(state = {}, action) { 8 | switch (action.type) { 9 | //target 10 | 11 | case SIGN_IN: 12 | console.log("signin status " + action.payload) 13 | return { 14 | signin_status: action.payload 15 | } 16 | 17 | default: 18 | return state; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_updateProfile.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { UPDATE_PROF} from "../actions/userActions"; 3 | 4 | 5 | //Reducer listening to different action types 6 | //initial state is {} 7 | export default function(state = {}, action) { 8 | switch (action.type) { 9 | //target 10 | 11 | case UPDATE_PROF: 12 | console.log("prof update status " + action.payload) 13 | return { 14 | status: action.payload 15 | } 16 | 17 | default: 18 | return state; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /frontend/src/store.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from 'redux'; 2 | import thunk from 'redux-thunk'; 3 | import rootReducer from './reducers'; 4 | import promise from "redux-promise"; 5 | 6 | const initialState = {}; 7 | 8 | const middleware = [thunk]; 9 | 10 | const store = createStore( 11 | rootReducer, 12 | initialState, 13 | compose( 14 | applyMiddleware(...middleware), 15 | window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 16 | ) 17 | ); 18 | 19 | export default store; 20 | -------------------------------------------------------------------------------- /kafka-backend/model/course_announce.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | const db = require("./dbconn") 4 | 5 | var announceSchema = mongoose.Schema({ 6 | course_id: { 7 | type: String, 8 | }, 9 | title: { 10 | type: String 11 | }, 12 | posted_on: { 13 | type: String 14 | }, 15 | content: { 16 | type: String 17 | } 18 | }) 19 | Announce = module.exports = mongoose.model('announces',announceSchema); 20 | module.exports = Announce -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_dispProfile.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { FETCH_PROFILE} from "../actions/userActions"; 3 | 4 | const initialState = { 5 | items: [] 6 | } 7 | 8 | //Reducer listening to different action types 9 | //initial state is {} 10 | export default function(state = initialState, action) { 11 | switch (action.type) { 12 | //target 13 | case FETCH_PROFILE: 14 | return { 15 | ...state, 16 | items: action.payload 17 | } 18 | 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /frontend/src/reducers/reducer_createCourse.js: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | import { CREATE_COURSE } from "../actions/courseActions"; 3 | 4 | 5 | //Reducer listening to different action types 6 | //initial state is {} 7 | export default function(state = {}, action) { 8 | switch (action.type) { 9 | //target 10 | 11 | case CREATE_COURSE: 12 | console.log("create course status " + action.payload) 13 | return { 14 | createcourse_status: action.payload 15 | } 16 | 17 | default: 18 | return state; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /frontend/src/components/FileInput.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | class FileInput extends React.Component { 4 | constructor(props) { 5 | super(props) 6 | this.onChange = this.onChange.bind(this) 7 | } 8 | 9 | onChange(e) { 10 | const { input: { onChange } } = this.props 11 | onChange(e.target.files[0]) 12 | } 13 | 14 | render() { 15 | const { input: { value } } = this.props 16 | 17 | return () 22 | } 23 | } 24 | 25 | export default FileInput -------------------------------------------------------------------------------- /frontend/src/App.js: -------------------------------------------------------------------------------- 1 | // App.js 2 | 3 | import React, { Component } from 'react'; 4 | import Main from './components/Main'; 5 | import {BrowserRouter} from 'react-router-dom'; 6 | import './App.css'; 7 | import { Provider } from 'react-redux'; 8 | import store from './store'; 9 | 10 | 11 | class App extends Component { 12 | 13 | render() { 14 | return ( 15 | 16 | 17 | 18 | {/* App Child Component Main*/} 19 |
20 | 21 | 22 | 23 | ); 24 | } 25 | 26 | } 27 | 28 | export default App; 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /frontend/src/components/MenuItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import {Link} from 'react-router-dom'; 4 | 5 | 6 | const MenuItem = (props) => { 7 | const { label, link, icon, onDrawerToggleClick } = props; 8 | return ( 9 |
  • 10 | 11 | {label} 12 | 13 |
  • 14 | ); 15 | }; 16 | 17 | MenuItem.propTypes = { 18 | label: PropTypes.string, 19 | link: PropTypes.string, 20 | }; 21 | 22 | MenuItem.defaultProps = { 23 | label: 'Label', 24 | link: '/', 25 | }; 26 | 27 | export default MenuItem; -------------------------------------------------------------------------------- /backend/model/course_assignment.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | //const db = require("./dbconn") 4 | 5 | var assignmentSchema = mongoose.Schema({ 6 | course_id: { 7 | type: String, 8 | }, 9 | title: { 10 | type: String 11 | }, 12 | due_date: { 13 | type: String 14 | }, 15 | posted_on: { 16 | type: String 17 | }, 18 | content: { 19 | type: String 20 | }, 21 | total_points: { 22 | type: Number 23 | } 24 | }) 25 | Assigns = module.exports = mongoose.model('assignments',assignmentSchema); 26 | module.exports = Assigns -------------------------------------------------------------------------------- /backend/model/course_grades.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var gradeSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String 5 | }, 6 | task_id: { 7 | type: String 8 | }, 9 | task_type: { 10 | type: String 11 | }, 12 | 13 | task_title: { 14 | type: String 15 | }, 16 | task_grade: { 17 | type: Number,default: 0 18 | }, 19 | task_outof: { 20 | type: Number,default: 0 21 | }, 22 | user_email: { 23 | type: String 24 | } 25 | }) 26 | module.exports = mongoose.model('grades',gradeSchema); -------------------------------------------------------------------------------- /kafka-backend/model/course_assignment.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | const db = require("./dbconn") 4 | 5 | var assignmentSchema = mongoose.Schema({ 6 | course_id: { 7 | type: String, 8 | }, 9 | title: { 10 | type: String 11 | }, 12 | due_date: { 13 | type: String 14 | }, 15 | posted_on: { 16 | type: String 17 | }, 18 | content: { 19 | type: String 20 | }, 21 | total_points: { 22 | type: Number 23 | }, 24 | }) 25 | Assigns = module.exports = mongoose.model('assignments',assignmentSchema); 26 | module.exports = Assigns -------------------------------------------------------------------------------- /frontend/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | import { reducer as formReducer } from "redux-form"; 3 | import ProfileReducer from "./reducer_dispProfile"; 4 | import SignUpReducer from "./reducer_signUp"; 5 | import SignInReducer from "./reducer_signin"; 6 | import NewMsgReducer from "./reducer_newMsg"; 7 | import CourseCreateReducer from "./reducer_createCourse"; 8 | 9 | const rootReducer = combineReducers({ 10 | profile: ProfileReducer, 11 | form: formReducer, 12 | signup_status: SignUpReducer, 13 | signin_status: SignInReducer, 14 | newmsg_status: NewMsgReducer, 15 | createcourse_status: CourseCreateReducer, 16 | }); 17 | 18 | export default rootReducer; 19 | -------------------------------------------------------------------------------- /kafka-backend/model/course_grades.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | const db = require("./dbconn") 3 | 4 | var gradeSchema = mongoose.Schema({ 5 | course_id: { 6 | type: String 7 | }, 8 | task_id: { 9 | type: String 10 | }, 11 | task_type: { 12 | type: String 13 | }, 14 | 15 | task_title: { 16 | type: String 17 | }, 18 | task_grade: { 19 | type: Number,default: 0 20 | }, 21 | task_outof: { 22 | type: Number,default: 0 23 | }, 24 | user_email: { 25 | type: String 26 | } 27 | }) 28 | module.exports = mongoose.model('grades',gradeSchema); -------------------------------------------------------------------------------- /backend/model/user_assignments.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var userAssignSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String 5 | }, 6 | title: { 7 | type: String 8 | }, 9 | assn_id: { 10 | type: String 11 | }, 12 | submitted_on: { 13 | type: String 14 | }, 15 | user_file: { 16 | type: String 17 | }, 18 | user_email: { 19 | type: String 20 | }, 21 | total_points: { 22 | type: Number 23 | } 24 | 25 | }) 26 | const UserAssign = module.exports = mongoose.model('user_assignments',userAssignSchema); 27 | 28 | module.exports = UserAssign; 29 | -------------------------------------------------------------------------------- /backend/model/student_course.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var studentCourseSchema = mongoose.Schema({ 3 | 4 | user_email: { 5 | type: String, 6 | }, 7 | user_course: { 8 | type: String, 9 | }, 10 | course_assignment1: { 11 | type: String, 12 | }, 13 | course_assignment2: { 14 | type: String 15 | }, 16 | course_assignment1_grade: { 17 | type: String 18 | }, 19 | course_assignment2_grade: { 20 | type: String 21 | }, 22 | course_quiz1: { 23 | type: String 24 | }, 25 | course_quiz2: { 26 | type: String 27 | }, 28 | course_quiz1_grade: { 29 | type: String 30 | }, 31 | course_quiz2_grade: { 32 | type: String 33 | } 34 | }); 35 | 36 | const student_course = module.exports = mongoose.model('studentCourse',studentCourseSchema); -------------------------------------------------------------------------------- /kafka-backend/model/student_course.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var studentCourseSchema = mongoose.Schema({ 3 | 4 | user_email: { 5 | type: String, 6 | }, 7 | user_course: { 8 | type: String, 9 | }, 10 | course_assignment1: { 11 | type: String, 12 | }, 13 | course_assignment2: { 14 | type: String 15 | }, 16 | course_assignment1_grade: { 17 | type: String 18 | }, 19 | course_assignment2_grade: { 20 | type: String 21 | }, 22 | course_quiz1: { 23 | type: String 24 | }, 25 | course_quiz2: { 26 | type: String 27 | }, 28 | course_quiz1_grade: { 29 | type: String 30 | }, 31 | course_quiz2_grade: { 32 | type: String 33 | } 34 | }); 35 | 36 | const student_course = module.exports = mongoose.model('studentCourse',studentCourseSchema); -------------------------------------------------------------------------------- /kafka-backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "back-end", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcrypt": "^3.0.5", 13 | "formidable": "^1.1.1", 14 | "glob": "^7.1.2", 15 | "images-upload-middleware": "^1.1.1", 16 | "jsonwebtoken": "^8.5.1", 17 | "kafka-node": "^2.5.0", 18 | "mongo": "^0.1.0", 19 | "mongodb": "^2.2.31", 20 | "mongodb-autoincrement": "^1.0.1", 21 | "mongoose": "^5.5.0", 22 | "multer": "^1.3.0", 23 | "nodemailer": "^4.6.4", 24 | "passport": "^0.4.0", 25 | "passport-local": "^1.0.0", 26 | "uuidv4": "^1.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /kafka-backend/model/user_assignments.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | const db = require("./dbconn") 3 | var userAssignSchema = mongoose.Schema({ 4 | course_id: { 5 | type: String 6 | }, 7 | title: { 8 | type: String 9 | }, 10 | assn_id: { 11 | type: String 12 | }, 13 | submitted_on: { 14 | type: String 15 | }, 16 | user_file: { 17 | type: String 18 | }, 19 | user_email: { 20 | type: String 21 | }, 22 | total_points: { 23 | type: Number 24 | } 25 | 26 | }) 27 | const UserAssign = module.exports = mongoose.model('user_assignments',userAssignSchema); 28 | 29 | module.exports = UserAssign; 30 | -------------------------------------------------------------------------------- /frontend/src/actions/msgActions.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const WRITE_MSG = 'WRITE_MSG'; 4 | 5 | 6 | const ROOT_URL = "/users"; 7 | 8 | var accessToken = localStorage.getItem('usertoken') 9 | 10 | 11 | // Set the AUTH token for any request 12 | axios.interceptors.request.use(function (config) { 13 | const token = localStorage.getItem('usertoken'); 14 | config.headers.Authorization = token ? `Bearer ${token}` : ''; 15 | return config; 16 | }); 17 | 18 | 19 | export const newMsg = (values,callback) => dispatch => { 20 | console.log("accessToken: " + accessToken) 21 | axios.post(`${ROOT_URL}/messages`, values) 22 | .then(response => 23 | dispatch({ 24 | type: WRITE_MSG, 25 | payload: response.status 26 | }) 27 | ) 28 | .then(() => callback()); 29 | 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /frontend/src/components/SideMenu/SideMenu.css: -------------------------------------------------------------------------------- 1 | .side-menu { 2 | height: 13%; 3 | background: white; 4 | box-shadow: 1px 0px 7px rgba(0, 0, 0, 0.5); 5 | position: fixed; 6 | top: 350px; 7 | left: 230px; 8 | width: 50%; 9 | max-width: 190px; 10 | z-index: 200; 11 | transform: translateX(-100%); 12 | transition: transform 0.3s ease-out; 13 | } 14 | 15 | .side-menu-fixed { 16 | height: 100%; 17 | background: white; 18 | box-shadow: 1px 0px 7px rgba(0, 0, 0, 0.5); 19 | position: fixed; 20 | top: 56px; 21 | left: 230px; 22 | width: 50%; 23 | max-width: 190px; 24 | z-index: 200; 25 | transform: translateX(-100%); 26 | transition: transform 0.3s ease-out; 27 | } 28 | 29 | .side-menu.open { 30 | transform: translateX(0); 31 | } 32 | 33 | .side-menu-fixed.open { 34 | transform: translateX(0); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /backend/model/course_quiz.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var quizSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String, 5 | }, 6 | title: { 7 | type: String 8 | }, 9 | posted_on: { 10 | type: String 11 | }, 12 | due_date: { 13 | type: String 14 | }, 15 | questions: [{ 16 | question: { 17 | type: String 18 | }, 19 | answers: [ 20 | { 21 | is_correct: {type: Boolean} 22 | , 23 | value: {type: String} 24 | } 25 | ] 26 | 27 | }] 28 | 29 | 30 | }) 31 | const Quiz = module.exports = mongoose.model('quiz',quizSchema); 32 | 33 | module.exports = Quiz; 34 | -------------------------------------------------------------------------------- /kafka-backend/model/course_quiz.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | const db = require("./dbconn") 3 | var quizSchema = mongoose.Schema({ 4 | course_id: { 5 | type: String, 6 | }, 7 | title: { 8 | type: String 9 | }, 10 | posted_on: { 11 | type: String 12 | }, 13 | due_date: { 14 | type: String 15 | }, 16 | questions: [{ 17 | question: { 18 | type: String 19 | }, 20 | answers: [ 21 | { 22 | is_correct: {type: Boolean} 23 | , 24 | value: {type: String} 25 | } 26 | ] 27 | 28 | }] 29 | 30 | 31 | }) 32 | const Quiz = module.exports = mongoose.model('quiz',quizSchema); 33 | 34 | module.exports = Quiz; 35 | -------------------------------------------------------------------------------- /frontend/src/components/SideMenu/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | //import MenuItem from '../MenuItem'; 4 | import {Link} from 'react-router-dom'; 5 | 6 | import './SideMenu.css'; 7 | 8 | const SideMenu = (props) => { 9 | const { opened } = props; 10 | const cssClasses = opened ? 'side-menu open' : 'side-menu'; 11 | 12 | return ( 13 | 20 | ); 21 | }; 22 | 23 | SideMenu.propTypes = { 24 | menuItems: PropTypes.array, 25 | opened: PropTypes.bool, 26 | }; 27 | 28 | SideMenu.defaultProps = { 29 | menuItems: [], 30 | opened: false, 31 | }; 32 | 33 | export default SideMenu; 34 | -------------------------------------------------------------------------------- /frontend/src/components/ListBody.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const styles = { 4 | wrapper: { 5 | display: "flex", 6 | flexDirection: "column", 7 | alignItems: "flex-start", 8 | padding: "1.2em" 9 | }, 10 | name: { 11 | fontSize: "1.5em" 12 | }, 13 | description: { 14 | fontSize: "1.1em" 15 | } 16 | }; 17 | /* 18 | const ListBody = ({ course_id, course_name, course_dep, course_term }) => ( 19 |
    20 | {course_term} {course_dep} {course_id} 21 | {course_name} 22 |
    23 | ); 24 | */ 25 | const ListBody = ({ course_id, course_dep, course_name }) => ( 26 |
    27 | 28 | {course_dep} {course_id} 29 | {course_name} 30 |
    31 | ); 32 | export default ListBody; 33 | -------------------------------------------------------------------------------- /frontend/src/actions/courseActions.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const CREATE_COURSE = 'CREATE_COURSE'; 4 | 5 | 6 | const ROOT_URL = "/course"; 7 | 8 | var accessToken = localStorage.getItem('usertoken') 9 | 10 | 11 | 12 | // Set the AUTH token for any request 13 | axios.interceptors.request.use(function (config) { 14 | const token = localStorage.getItem('usertoken'); 15 | config.headers.Authorization = token ? `Bearer ${token}` : ''; 16 | return config; 17 | }); 18 | 19 | export const createCourse = (values,callback) => dispatch => { 20 | // let accessToken = localStorage.getItem('usertoken') 21 | console.log("accessToken: " + accessToken) 22 | axios.post(`${ROOT_URL}/coursecreate`, values) 23 | .then(response => 24 | dispatch({ 25 | type: CREATE_COURSE, 26 | payload: response.status 27 | }) 28 | ) 29 | .then(() => callback()); 30 | 31 | }; 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /frontend/src/components/Home.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Header from './Header'; 3 | import SideBar from './SideBar'; 4 | import Content from './Content'; 5 | import SideMenu from './SideMenu' 6 | 7 | class Home extends Component { 8 | 9 | state = { 10 | sideDrawerVisible: false, 11 | } 12 | 13 | handleDrawerToggleClick = () => { 14 | this.setState(prevState => ({ 15 | sideDrawerVisible: !prevState.sideDrawerVisible, 16 | })); 17 | } 18 | 19 | handleBackdropClick = () => { 20 | this.setState({ 21 | sideDrawerVisible: false, 22 | }); 23 | } 24 | 25 | render() { 26 | const { sideDrawerVisible } = this.state; 27 | return ( 28 |
    29 |
    30 | 31 | {sideDrawerVisible 32 | ? ( 33 | 34 | 35 | 36 | ) : null 37 | } 38 | 39 |
    40 | ); 41 | } 42 | } 43 | 44 | export default Home; -------------------------------------------------------------------------------- /kafka-backend/services/msgBySubject.js: -------------------------------------------------------------------------------- 1 | console.log("in msg by subject") 2 | 3 | var User = require("../model/message"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | var subject = msg.subject; 9 | 10 | var res = {}; 11 | 12 | Message.find( { $and:[{subject: subject}, {$or:[ {user_email: msg.email}, {to_email:msg.email}]}]} ) 13 | // Message.find( {user_email: user.user_email}) 14 | .select('user_email to_email subject message') 15 | .exec() 16 | .then(messages => { 17 | if (messages) { 18 | // res=messages 19 | callback(null, messages); 20 | }}) 21 | .catch(err => { 22 | console.log("first error" + err); 23 | res=({"Message": err, status: "false", code: "500"}); 24 | callback(null, res); 25 | }) 26 | } 27 | 28 | exports.handle_request = handle_request; -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "server for canvas application", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha test" 8 | }, 9 | "author": "Rakhee Singh", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcrypt": "^3.0.4", 13 | "bcryptjs": "^2.4.3", 14 | "chai": "^4.2.0", 15 | "chai-http": "^4.2.1", 16 | "connect-multiparty": "^2.2.0", 17 | "cookie-parser": "^1.4.4", 18 | "cors": "^2.8.5", 19 | "express": "^4.16.4", 20 | "form-data": "^2.3.3", 21 | "http": "0.0.0", 22 | "jsonwebtoken": "^8.5.0", 23 | "kafka-node": "^4.1.0", 24 | "mocha": "^6.1.3", 25 | "mongoose": "^5.4.19", 26 | "multer": "^1.4.1", 27 | "multiparty": "^4.2.1", 28 | "mysql": "^2.16.0", 29 | "mysql2": "^1.6.5", 30 | "passport": "^0.4.0", 31 | "passport-jwt": "^4.0.0", 32 | "passport-local": "^1.0.0", 33 | "passport-local-mongoose": "^5.0.1", 34 | "sequelize": "^4.42.1", 35 | "socket.io": "^2.2.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /kafka-backend/services/getQuizById.js: -------------------------------------------------------------------------------- 1 | console.log("in get quiz by Id") 2 | 3 | var Quiz = require("../model/course_quiz"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.quiz_id) 9 | var res = {}; 10 | 11 | Quiz.findOne({ 12 | _id: msg.quiz_id, 13 | }) 14 | .then(quiz => { 15 | if (quiz) { 16 | console.log("user :" + JSON.stringify(quiz)) 17 | 18 | // res=(user: quiz, code: "200"}); 19 | 20 | callback(null, quiz); 21 | // res.status(200).json(user) 22 | }else { 23 | res=({code: "404"}); 24 | callback(null, res); 25 | } 26 | }) 27 | .catch(err => { 28 | console.log("Error case.." + err); 29 | res=({code: "500"}); 30 | callback(null, res); 31 | }) 32 | 33 | } 34 | 35 | exports.handle_request = handle_request; 36 | 37 | 38 | -------------------------------------------------------------------------------- /backend/model/course.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var courseSchema = mongoose.Schema({ 3 | course_id: { 4 | type: String, 5 | primaryKey: true 6 | }, 7 | course_name: { 8 | type: String 9 | }, 10 | course_dep: { 11 | type: String 12 | }, 13 | course_desc: { 14 | type: String 15 | }, 16 | course_term: { 17 | type: String 18 | }, 19 | course_room: { 20 | type: String 21 | }, 22 | course_cap: { 23 | type: Number, default: 0 24 | }, 25 | course_wl_cap: { 26 | type: Number, default: 0 27 | }, 28 | course_enrollment_count: { 29 | type: Number, default: 0 30 | }, 31 | course_wl_count: { 32 | type: Number, default: 0 33 | }, 34 | course_creator: { 35 | type: String 36 | } 37 | }) 38 | const Course = module.exports = mongoose.model('courses',courseSchema); -------------------------------------------------------------------------------- /kafka-backend/services/getLectures.js: -------------------------------------------------------------------------------- 1 | console.log("in get all lectures by course Id") 2 | 3 | var Lectures = require("../model/course_lectures"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.course_id) 9 | var res = {}; 10 | 11 | Lectures.find({ 12 | course_id: msg.course_id, 13 | }) 14 | .then(lecs => { 15 | if (lecs) { 16 | console.log("user :" + JSON.stringify(lecs)) 17 | 18 | res=({user: JSON.stringify(lecs), code: "200"}); 19 | callback(null, res); 20 | // res.status(200).json(user) 21 | }else { 22 | res=({code: "204"}); 23 | callback(null, res); 24 | } 25 | }) 26 | .catch(err => { 27 | console.log("Error case.." + err); 28 | res=({code: "500"}); 29 | callback(null, res); 30 | }) 31 | 32 | } 33 | 34 | exports.handle_request = handle_request; 35 | 36 | 37 | -------------------------------------------------------------------------------- /kafka-backend/services/subassigns.js: -------------------------------------------------------------------------------- 1 | console.log("in get all assignments submitted") 2 | 3 | var UserAssign = require("../model/user_assignments"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.course_id) 9 | var res = {}; 10 | 11 | UserAssign.find({ 12 | course_id: msg.course_id, 13 | }) 14 | .then(assignments => { 15 | if (assignments) { 16 | console.log("user :" + JSON.stringify(assignments)) 17 | 18 | res=({user: assignments, code: "200"}); 19 | callback(null, res); 20 | // res.status(200).json(user) 21 | }else { 22 | res=({code: "204"}); 23 | callback(null, res); 24 | } 25 | }) 26 | .catch(err => { 27 | console.log("Error case.." + err); 28 | res=({code: "500"}); 29 | callback(null, res); 30 | }) 31 | 32 | } 33 | 34 | exports.handle_request = handle_request; 35 | 36 | 37 | -------------------------------------------------------------------------------- /kafka-backend/services/getAssignmentById.js: -------------------------------------------------------------------------------- 1 | console.log("in get assignmnent by Id") 2 | 3 | var Assigns = require("../model/course_assignment"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.assn_id) 9 | var res = {}; 10 | 11 | Assigns.findOne({ 12 | _id: msg.assn_id, 13 | }) 14 | .then(assignment => { 15 | if (assignment) { 16 | console.log("user :" + JSON.stringify(assignment)) 17 | 18 | // res=(user: assignment, code: "200"}); 19 | 20 | callback(null, assignment); 21 | // res.status(200).json(user) 22 | }else { 23 | res=({code: "404"}); 24 | callback(null, res); 25 | } 26 | }) 27 | .catch(err => { 28 | console.log("Error case.." + err); 29 | res=({code: "500"}); 30 | callback(null, res); 31 | }) 32 | 33 | } 34 | 35 | exports.handle_request = handle_request; 36 | 37 | 38 | -------------------------------------------------------------------------------- /kafka-backend/services/getAssignments.js: -------------------------------------------------------------------------------- 1 | console.log("in get all assignments by course Id") 2 | 3 | var User = require("../model/course_assignment"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.course_id) 9 | var res = {}; 10 | 11 | Assigns.find({ 12 | course_id: msg.course_id, 13 | }) 14 | .then(assignments => { 15 | if (assignments) { 16 | console.log("user :" + JSON.stringify(assignments)) 17 | 18 | res=({user: JSON.stringify(assignments), code: "200"}); 19 | callback(null, res); 20 | // res.status(200).json(user) 21 | }else { 22 | res=({code: "204"}); 23 | callback(null, res); 24 | } 25 | }) 26 | .catch(err => { 27 | console.log("Error case.." + err); 28 | res=({code: "500"}); 29 | callback(null, res); 30 | }) 31 | 32 | } 33 | 34 | exports.handle_request = handle_request; 35 | 36 | 37 | -------------------------------------------------------------------------------- /kafka-backend/kafka/Connection.js: -------------------------------------------------------------------------------- 1 | var kafka = require('kafka-node'); 2 | 3 | function ConnectionProvider() { 4 | this.getConsumer = function(topic_name) { 5 | 6 | this.client = new kafka.Client("localhost:2181"); 7 | this.kafkaConsumerConnection = new kafka.Consumer(this.client,[ { topic: topic_name, partition: 0 }]); 8 | this.client.on('ready', function () { console.log('client ready!') }) 9 | 10 | return this.kafkaConsumerConnection; 11 | }; 12 | 13 | //Code will be executed when we start Producer 14 | this.getProducer = function() { 15 | 16 | if (!this.kafkaProducerConnection) { 17 | this.client = new kafka.Client("localhost:2181"); 18 | var HighLevelProducer = kafka.HighLevelProducer; 19 | this.kafkaProducerConnection = new HighLevelProducer(this.client); 20 | //this.kafkaConnection = new kafka.Producer(this.client); 21 | console.log('producer ready'); 22 | } 23 | return this.kafkaProducerConnection; 24 | }; 25 | } 26 | exports = module.exports = new ConnectionProvider; -------------------------------------------------------------------------------- /kafka-backend/services/getAnnouncements.js: -------------------------------------------------------------------------------- 1 | console.log("in get dashboard courses") 2 | 3 | var Announce = require("../model/course_announce"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.course_id) 9 | var res = {}; 10 | 11 | Announce.find({ 12 | course_id: msg.course_id, 13 | }) 14 | .then(announcements => { 15 | if (announcements) { 16 | console.log("user :" + JSON.stringify(announcements)) 17 | 18 | res=({user: JSON.stringify(announcements), code: "200"}); 19 | callback(null, res); 20 | // res.status(200).json(user) 21 | }else { 22 | res=({code: "204"}); 23 | callback(null, res); 24 | } 25 | }) 26 | .catch(err => { 27 | console.log("Error case.." + err); 28 | res=({code: "500"}); 29 | callback(null, res); 30 | }) 31 | 32 | } 33 | 34 | exports.handle_request = handle_request; 35 | 36 | 37 | -------------------------------------------------------------------------------- /kafka-backend/services/replytomsg.js: -------------------------------------------------------------------------------- 1 | console.log("in replytomsg service") 2 | 3 | var Message = require("../model/message"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg) + " " + msg.email); 7 | var res = {}; 8 | 9 | var message = new Message({user_email: msg.email, to_email: msg.to_email, subject: msg.subject, message: msg.message }); 10 | 11 | message.save() 12 | .then(messages => { 13 | if (messages) { 14 | console.log("message created" + JSON.stringify(messages)); 15 | res=({user: messages, status: "true", code: "201"}); 16 | // res=messages 17 | callback(null, res); 18 | //res.status(200).json(user) 19 | }}) 20 | .catch(err => { 21 | console.log("Error case.." + err); 22 | res=({"Message": err, status: "false", code: "500"}); 23 | callback(null, res); 24 | // res.status(500).json({ error: err }) 25 | }) 26 | } 27 | 28 | exports.handle_request = handle_request; 29 | -------------------------------------------------------------------------------- /frontend/src/components/Quiz/Question.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class Question extends Component { 4 | 5 | 6 | render(){ 7 | var optionsNodes = Object.keys(this.props.data.answers).map(function(value, index){ 8 | return ( 9 |
    10 | 17 | 20 |
    21 | ) 22 | }.bind(this)); 23 | 24 | return ( 25 |
    26 |

    27 | {(parseInt(this.props.id) + 1) + ") " + this.props.data.question}

    28 | 29 | {optionsNodes} 30 |
    31 | 34 | 35 |
    36 | ); 37 | } 38 | } 39 | 40 | export default Question 41 | -------------------------------------------------------------------------------- /kafka-backend/services/announcement.js: -------------------------------------------------------------------------------- 1 | console.log("in post announcement service") 2 | 3 | var Message = require("../model/course_announce"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | var res = {}; 8 | 9 | const announceFields = new Announce({ 10 | course_id: msg.course_id, 11 | title: msg.title, 12 | posted_on: msg.posted_on, 13 | content: msg.content 14 | }) 15 | announceFields 16 | .save() 17 | .then(anc => { 18 | if (anc) { 19 | console.log("announcement created" + JSON.stringify(anc)); 20 | res=({user: anc, code: "200"}); 21 | // res=messages 22 | callback(null, res); 23 | //res.status(200).json(user) 24 | }}) 25 | .catch(err => { 26 | console.log("Error case.." + err); 27 | res=({"Message": err, code: "500"}); 28 | callback(null, res); 29 | // res.status(500).json({ error: err }) 30 | }) 31 | } 32 | 33 | exports.handle_request = handle_request; 34 | -------------------------------------------------------------------------------- /kafka-backend/services/addcourse.js: -------------------------------------------------------------------------------- 1 | console.log("in addcourse service") 2 | 3 | var User = require("../model/user"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:" + " " + msg.course_id + " " + msg.course_name + msg.user_email); 7 | var res = {}; 8 | 9 | var user_course = {course_id: msg.course_id, course_name:msg.course_name} 10 | User.findOneAndUpdate({user_email: msg.user_email}, 11 | {$push:{user_courses:user_course} } 12 | 13 | ) 14 | .then(messages => { 15 | if (messages) { 16 | console.log("message created" + JSON.stringify(messages)); 17 | res=({user: messages, status: "true", code: "200"}); 18 | // res=messages 19 | callback(null, res); 20 | //res.status(200).json(user) 21 | }}) 22 | .catch(err => { 23 | console.log("Error case.." + err); 24 | res=({"Message": err, status: "false", code: "500"}); 25 | callback(null, res); 26 | // res.status(500).json({ error: err }) 27 | }) 28 | } 29 | 30 | exports.handle_request = handle_request; 31 | -------------------------------------------------------------------------------- /kafka-backend/services/removestudent.js: -------------------------------------------------------------------------------- 1 | console.log("in removestudent service") 2 | 3 | var User = require("../model/user"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:" + " " + msg.course_id + " " + msg.user_email); 7 | var res = {}; 8 | 9 | // var user_course = {course_id: msg.course_id, course_name:msg.course_name} 10 | User.findOneAndUpdate({user_email: msg.user_email}, 11 | {$pull:{user_courses:{course_id:msg.course_id} } } 12 | 13 | ) 14 | .then(messages => { 15 | if (messages) { 16 | console.log("message created" + JSON.stringify(messages)); 17 | res=({user: messages, status: "true", code: "200"}); 18 | // res=messages 19 | callback(null, res); 20 | //res.status(200).json(user) 21 | }}) 22 | .catch(err => { 23 | console.log("Error case.." + err); 24 | res=({"Message": err, status: "false", code: "500"}); 25 | callback(null, res); 26 | // res.status(500).json({ error: err }) 27 | }) 28 | } 29 | 30 | exports.handle_request = handle_request; 31 | -------------------------------------------------------------------------------- /kafka-backend/model/course.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | //console.log("in model course") 4 | const db = require("./dbconn") 5 | //console.log("in model course after") 6 | 7 | var courseSchema = mongoose.Schema({ 8 | course_id: { 9 | type: String, 10 | primaryKey: true 11 | }, 12 | course_name: { 13 | type: String 14 | }, 15 | course_dep: { 16 | type: String 17 | }, 18 | course_desc: { 19 | type: String 20 | }, 21 | course_term: { 22 | type: String 23 | }, 24 | course_room: { 25 | type: String 26 | }, 27 | course_cap: { 28 | type: Number, default: 0 29 | }, 30 | course_wl_cap: { 31 | type: Number, default: 0 32 | }, 33 | course_enrollment_count: { 34 | type: Number, default: 0 35 | }, 36 | course_wl_count: { 37 | type: Number, default: 0 38 | }, 39 | course_creator: { 40 | type: String 41 | } 42 | }) 43 | Course = module.exports = mongoose.model('courses',courseSchema); 44 | 45 | module.exports = Course; -------------------------------------------------------------------------------- /kafka-backend/services/assignment.js: -------------------------------------------------------------------------------- 1 | console.log("in post assignment service") 2 | 3 | var Message = require("../model/course_assignment"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | var res = {}; 8 | 9 | const assignsFields = new Assigns({ 10 | course_id: msg.course_id, 11 | title: msg.title, 12 | due_date: msg.due_date, 13 | posted_on: msg.posted_on, 14 | content: msg.content, 15 | total_points: msg.total_points, 16 | }) 17 | assignsFields 18 | .save() 19 | .then(asn => { 20 | if (asn) { 21 | console.log("assignment created" + JSON.stringify(asn)); 22 | res=({user: asn, code: "201"}); 23 | // res=messages 24 | callback(null, res); 25 | //res.status(200).json(user) 26 | }}) 27 | .catch(err => { 28 | console.log("Error case.." + err); 29 | res=({"Message": err, code: "500"}); 30 | callback(null, res); 31 | // res.status(500).json({ error: err }) 32 | }) 33 | } 34 | 35 | exports.handle_request = handle_request; 36 | -------------------------------------------------------------------------------- /backend/model/user.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | var userSchema = mongoose.Schema({ 3 | user_name: { 4 | type: String, required: true 5 | }, 6 | user_email: { 7 | type: String, required: true 8 | }, 9 | user_password: { 10 | type: String, required: true 11 | }, 12 | user_type: { 13 | type: String, required: true 14 | }, 15 | user_about_me: { 16 | type: String 17 | }, 18 | session_id: { 19 | type: String 20 | }, 21 | user_phone: { 22 | type: String 23 | }, 24 | user_about_me: { 25 | type: String 26 | }, 27 | user_city: { 28 | type: String 29 | }, 30 | user_country: { 31 | type: String 32 | }, 33 | user_company: { 34 | type: String 35 | }, 36 | user_school: { 37 | type: String 38 | }, 39 | user_hometown: { 40 | type: String 41 | }, 42 | user_language: { 43 | type: String 44 | }, 45 | user_gender: { 46 | type: String 47 | }, 48 | user_photo: { 49 | type: String 50 | }, 51 | user_courses: [{ 52 | course_id: {type: String}, 53 | course_name: {type: String}, 54 | assignments:[{ title:{type:String },assn_id:{type:String},user_file: { type:String } }] 55 | }] 56 | }); 57 | 58 | const User = module.exports = mongoose.model('users',userSchema); 59 | 60 | module.exports = User; -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 16 | Canvas Application 17 | 18 | 19 |
    20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /kafka-backend/model/user.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'); 2 | 3 | //console.log("in model user") 4 | //const db = require("./dbconn") 5 | //console.log("in model course after") 6 | 7 | var userSchema = mongoose.Schema({ 8 | user_name: { 9 | type: String, required: true 10 | }, 11 | user_email: { 12 | type: String, required: true 13 | }, 14 | user_password: { 15 | type: String, required: true 16 | }, 17 | user_type: { 18 | type: String, required: true 19 | }, 20 | user_about_me: { 21 | type: String 22 | }, 23 | session_id: { 24 | type: String 25 | }, 26 | user_phone: { 27 | type: String 28 | }, 29 | user_about_me: { 30 | type: String 31 | }, 32 | user_city: { 33 | type: String 34 | }, 35 | user_country: { 36 | type: String 37 | }, 38 | user_company: { 39 | type: String 40 | }, 41 | user_school: { 42 | type: String 43 | }, 44 | user_hometown: { 45 | type: String 46 | }, 47 | user_language: { 48 | type: String 49 | }, 50 | user_gender: { 51 | type: String 52 | }, 53 | user_photo: { 54 | type: String 55 | }, 56 | user_courses: [{ 57 | course_id: {type: String}, 58 | course_name: {type: String} 59 | }] 60 | }); 61 | 62 | User = module.exports = mongoose.model('users',userSchema); 63 | 64 | module.exports = User; -------------------------------------------------------------------------------- /kafka-backend/services/profilepic.js: -------------------------------------------------------------------------------- 1 | console.log("in profile service") 2 | 3 | 4 | var User = require("../model/user"); 5 | 6 | function handle_request(msg, callback){ 7 | console.log("In handle request:"+ JSON.stringify(msg)); 8 | 9 | console.log("email: " + msg.email) 10 | 11 | User.findOne({ 12 | // user_email: req.session.user 13 | user_email: msg.email 14 | }) .select('user_name user_email user_type user_photo') 15 | .exec() 16 | .then(user => { 17 | if (user) { 18 | console.log("record found" + user.user_phone); 19 | console.log("user found" + user); 20 | // res=({user: user, code: "200"}); 21 | res=user 22 | callback(null, user); 23 | //res.status(200).json(user) 24 | } 25 | else{ 26 | console.log("user not found" + user); 27 | res=({ code: "200"}); 28 | // res=user 29 | callback(null, res); 30 | } 31 | }) 32 | .catch(err => { 33 | console.log("Error case.." + err); 34 | res=({"Message": err, code: "500"}); 35 | callback(null, res); 36 | // res.status(500).json({ error: err }) 37 | }) 38 | } 39 | 40 | exports.handle_request = handle_request; 41 | 42 | 43 | -------------------------------------------------------------------------------- /kafka-backend/services/checkusercourse.js: -------------------------------------------------------------------------------- 1 | console.log("in check and enroll courses") 2 | 3 | var User = require("../model/user"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.user_email) 9 | var res = {}; 10 | 11 | User.find({ 12 | user_email: msg.user_email, 13 | user_courses: { 14 | $elemMatch: { 15 | course_id: msg.course_id 16 | // likes: ObjectId("593f8c591ba95154cfebe790") 17 | } 18 | } 19 | } 20 | ) 21 | .exec() 22 | .then(user => { 23 | console.log("result profile is: " + user) 24 | if (user=='') 25 | { 26 | console.log("result is empty") 27 | // res.status(204).send("course can be enrolled!!"); 28 | res=({user: user, code: "204"}); 29 | callback(null, res); 30 | }else{ 31 | //res.status(200).send("Course enrolled already, can only be dropped") 32 | res=({user: user, code: "200"}); 33 | callback(null, res); 34 | } 35 | }) 36 | .catch(err => { 37 | console.log("Error case.." + err); 38 | res=({code: "500"}); 39 | callback(null, res); 40 | }) 41 | 42 | } 43 | 44 | exports.handle_request = handle_request; 45 | 46 | 47 | -------------------------------------------------------------------------------- /kafka-backend/services/updateprofile.js: -------------------------------------------------------------------------------- 1 | console.log("in update profile service") 2 | 3 | var User = require("../model/user"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | var res = {}; 8 | console.log("email:" + msg.email ) 9 | User.findOneAndUpdate({user_email: msg.email}, 10 | { 11 | user_name: msg.user_name, 12 | user_phone: msg.user_phone, user_about_me: msg.user_about_me, 13 | user_city: msg.user_city, user_country: msg.user_country, 14 | user_company: msg.user_company, user_school: msg.user_school, 15 | user_hometown: msg.user_hometown, user_language: msg.user_language, 16 | user_gender: msg.user_gender 17 | // user_gender: msg.user_gender,user_photo: req.file.path 18 | }) 19 | .exec() 20 | .then(messages => { 21 | 22 | console.log("Profile updated " + JSON.stringify(messages)); 23 | res=({user: messages, status: "true", code: "200"}); 24 | // res=messages 25 | callback(null, res); 26 | //res.status(200).json(user) 27 | }) 28 | .catch(err => { 29 | console.log("Error case.." + err); 30 | res=({"Message": err, status: "false", code: "500"}); 31 | callback(null, res); 32 | // res.status(500).json({ error: err }) 33 | }) 34 | } 35 | 36 | exports.handle_request = handle_request; 37 | -------------------------------------------------------------------------------- /kafka-backend/services/sample_signin.js: -------------------------------------------------------------------------------- 1 | var mongo = require('./mongo'); 2 | var bcrypt = require('bcrypt'); 3 | 4 | 5 | function handle_request(msg, callback){ 6 | var res = {}; 7 | console.log("In handle request:"+ JSON.stringify(msg)); 8 | mongo.connect(function(err,db){ 9 | if(err){ 10 | callback(null,"Cannot connect to db"); 11 | } 12 | else{ 13 | console.log('Connected to mongodb'); 14 | var query = {Email : msg.username}; 15 | var dbo = db.db('usersignup'); 16 | dbo.collection("usersignup").find(query).toArray(function(err,result){ 17 | if(err){ 18 | callback(err,"Error"); 19 | } 20 | if(result.length > 0){ 21 | var hash = result[0].Password; 22 | bcrypt.compare(msg.password,hash,function(err,doesMatch){ 23 | if(doesMatch){ 24 | console.log("Inside result.length",result[0].userID); 25 | 26 | callback(null,result); 27 | } else { 28 | callback(null,[]); 29 | } 30 | }); 31 | } 32 | else{ 33 | callback(null,[]); 34 | } 35 | }); 36 | } 37 | }); 38 | 39 | } 40 | 41 | exports.handle_request = handle_request; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Canvas_LMS 2 | Learning management system using MERN stack, Kafka 3 | 4 | 5 | A) Basic Users (Student & faculty) functionalities: 6 | 1. Sign up new user (Name, Email and password) 7 | 2. Sign in existing user 8 | 3. Sign out. 9 | 4. Profile (Profile Image, Name, Email, Phone Number, About Me, City, Country, Company, School, Hometown, Languages, Gender) 10 | 5. Users can update Profile anytime. 11 | 12 | B) Faculty 13 | 1. Only the Faculty can create course with fields CourseId, CourseName, Course Dept, description, CourseRoom, Waitlist Capacity, CourseTeam. 14 | 15 | C) Home 16 | 1. Student can view all the courses he/she has registered. 17 | 2. Faculty can view all the courses created by them. 18 | 19 | D) Course Based: 20 | 1. Student actions: View Grades, Submit and view the submitted assignments, take quiz, view announcements, people registered for the course, download lecture notes and files. 21 | 2. Faculty actions: Create assignments, create quizzes, download submissions from students, make announcements, view students registered for a course, grade assignments for students, upload lecture notes and files, remove student from a course. 22 | 23 | E) Dashboard 24 | 1. The student dashboard with course cards are be made organizable. 25 | 2. User can move course cards to top, bottom and right. 26 | 27 | F) Messaging feature 28 | 1. Students can message other students. 29 | 2. Students can message Faculty. 30 | 3. Show the messages under Inbox Tab. 31 | 32 | G) Pagination feature added to People search, course search and other suitable views. 33 | -------------------------------------------------------------------------------- /kafka-backend/services/get_courses.js: -------------------------------------------------------------------------------- 1 | console.log("in get dashboard courses") 2 | 3 | var User = require("../model/user"); 4 | 5 | function handle_request(msg, callback){ 6 | console.log("In handle request:"+ JSON.stringify(msg)); 7 | 8 | console.log(msg.user_email) 9 | var res = {}; 10 | 11 | User.findOne({ 12 | user_email: msg.user_email 13 | }) .select('user_courses user_type') 14 | //}) .select('user_courses') 15 | .exec() 16 | .then(user => { 17 | if (user) { 18 | console.log("record found 1 " + user.user_courses); 19 | console.log("record found" + user.course_id); 20 | console.log("user found" + user); 21 | // res.status(200).json({user_photo: user.user_photo, user_name: user.user_name, user_email: user.user_email}) 22 | // res.send(JSON.stringify(user.user_courses)); 23 | res=({user: JSON.stringify(user), code: "200"}); 24 | // res=({user: JSON.stringify(user.user_courses), code: "200"}); 25 | callback(null, res); 26 | // res.status(200).json(user) 27 | }else { 28 | res=({code: "404"}); 29 | callback(null, res); 30 | } 31 | }) 32 | .catch(err => { 33 | console.log("Error case.." + err); 34 | res=({code: "500"}); 35 | callback(null, res); 36 | }) 37 | 38 | } 39 | 40 | exports.handle_request = handle_request; 41 | 42 | 43 | -------------------------------------------------------------------------------- /backend/kafka/connection.js: -------------------------------------------------------------------------------- 1 | var kafka = require('kafka-node'); 2 | 3 | function ConnectionProvider() { 4 | this.getConsumer = function(topic_name) { 5 | // if (!this.kafkaConsumerConnection) { 6 | 7 | this.client = new kafka.KafkaClient("localhost:2181"); 8 | /*this.client.refreshMetadata([{topic: topic_name}], (err) => { 9 | if (err) { 10 | console.warn('Error refreshing kafka metadata', err); 11 | } 12 | });*/ 13 | this.kafkaConsumerConnection = new kafka.Consumer(this.client,[ { topic: topic_name, partition: 0 }]); 14 | this.client.on('ready', function () { console.log('client ready!') }) 15 | // } 16 | return this.kafkaConsumerConnection; 17 | }; 18 | 19 | //Code will be executed when we start Producer 20 | this.getProducer = function() { 21 | 22 | if (!this.kafkaProducerConnection) { 23 | this.client = new kafka.KafkaClient("localhost:2181"); 24 | /*this.client.refreshMetadata([{topic: topic_name}], (err) => { 25 | if (err) { 26 | console.warn('Error refreshing kafka metadata', err); 27 | } 28 | });*/ 29 | var HighLevelProducer = kafka.HighLevelProducer; 30 | this.kafkaProducerConnection = new HighLevelProducer(this.client); 31 | //this.kafkaConnection = new kafka.Producer(this.client); 32 | console.log('producer ready'); 33 | } 34 | return this.kafkaProducerConnection; 35 | }; 36 | } 37 | exports = module.exports = new ConnectionProvider; -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^3.9.2", 7 | "@material-ui/icons": "^3.0.2", 8 | "axios": "^0.18.0", 9 | "bootstrap": "^4.3.1", 10 | "custom-error": "^0.2.1", 11 | "jquery": "^3.3.1", 12 | "jwt-decode": "^2.2.0", 13 | "material-ui": "^1.0.0-beta.47", 14 | "react": "^16.6.3", 15 | "react-bootstrap": "^1.0.0-beta.5", 16 | "react-burger-menu": "^2.6.5", 17 | "react-cookies": "^0.1.0", 18 | "react-dom": "^16.8.3", 19 | "react-file-viewer": "^1.1.0", 20 | "react-native": "^0.58.5", 21 | "react-native-elements": "^1.1.0", 22 | "react-native-vector-icons": "^6.3.0", 23 | "react-pdf-js": "^4.0.2", 24 | "react-redux": "^6.0.1", 25 | "react-router-dom": "^4.3.1", 26 | "react-scripts": "2.1.5", 27 | "react-sidebar": "^3.0.2", 28 | "reactstrap": "^7.1.0", 29 | "redux": "^4.0.1", 30 | "redux-devtools-extension": "^2.13.8", 31 | "redux-form": "^8.1.0", 32 | "redux-promise": "^0.6.0", 33 | "redux-thunk": "^2.3.0", 34 | "semantic-ui-react": "^0.85.0", 35 | "socket.io-client": "^2.2.0", 36 | "typescript": "^3.3.3333" 37 | }, 38 | "scripts": { 39 | "start": "react-scripts start", 40 | "build": "react-scripts build", 41 | "test": "react-scripts test", 42 | "eject": "react-scripts eject" 43 | }, 44 | "eslintConfig": { 45 | "extends": "react-app" 46 | }, 47 | "browserslist": [ 48 | ">0.2%", 49 | "not dead", 50 | "not ie <= 11", 51 | "not op_mini all" 52 | ], 53 | "proxy": "http://localhost:3001" 54 | } 55 | -------------------------------------------------------------------------------- /frontend/src/components/ListItem.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import ListBody from "./ListBody"; 3 | 4 | const styles = { 5 | li: { 6 | display: "flex", 7 | justifyContent: "flex-start", 8 | background: "white", 9 | boxShadow: "2px 4px 10px rgba(0, 0, 0, 0.2)", 10 | color: "#707070", 11 | marginBottom: "1em", 12 | marginRight: "1em", 13 | // cursor: "pointer", 14 | width: "19em", 15 | cursor: "move", 16 | }, 17 | leftWall: color => ({ 18 | width: "1.5em", 19 | backgroundColor: color 20 | }) 21 | }; 22 | 23 | export default class ListItem extends Component { 24 | // onDragStart = e => { 25 | // e.dataTransfer.effectAllowed = "move"; 26 | // e.dataTransfer.setData("text/html", e.target.parentNode); 27 | // e.dataTransfer.setDragImage(e.target.parentNode, 20, 20); 28 | // }; 29 | render() { 30 | return ( 31 |
  • this.props.handleOnClick(this.props.id)} 34 | > 35 |
    36 | 37 | 38 |
  • 39 | /*
  • this.props.handleOnClick(this.props.id)} 42 | > 43 |
    44 | 45 |
  • 46 | */ 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /kafka-backend/services/messagelist.js: -------------------------------------------------------------------------------- 1 | console.log("in messagelist service") 2 | 3 | 4 | var Message = require("../model/message"); 5 | 6 | function handle_request(msg, callback){ 7 | console.log("In handle request:"+ JSON.stringify(msg)); 8 | 9 | var email = msg.email; 10 | var res = {}; 11 | Message.aggregate([ 12 | { 13 | $match: { 14 | // "to_email":user.user_email, 15 | $or:[ {user_email: email}, {to_email:email}] 16 | } 17 | }, 18 | // {"$sort":{"subject":1}}, 19 | {"$group":{ 20 | "_id": "$subject",toemail: { $first: "$to_email"},fromemail:{ $first: "$user_email"}, 21 | // "_id": "$subject",emails: { $push: "$$ROOT" }, 22 | // "toemail": {"$to_email":"$$ROOT"} 23 | "subject": { "$last": "$subject" } 24 | }} 25 | ]) 26 | .exec() 27 | .then(messages => { 28 | if (messages) { 29 | console.log("variables" + messages.user_email ) 30 | console.log("user found" + JSON.stringify(messages)); 31 | // res=({user: user, status: "true", code: "200"}); 32 | // res=messages 33 | callback(null, messages); 34 | //res.status(200).json(user) 35 | }}) 36 | .catch(err => { 37 | console.log("Error case.." + err); 38 | res=({"Message": err, status: "false", code: "500"}); 39 | callback(null, res); 40 | // res.status(500).json({ error: err }) 41 | }) 42 | 43 | } 44 | 45 | exports.handle_request = handle_request; 46 | -------------------------------------------------------------------------------- /frontend/src/components/testcourse.css: -------------------------------------------------------------------------------- 1 | ul { 2 | padding: 0; 3 | margin: 20px; 4 | 5 | } 6 | 7 | .Tile { 8 | margin-top: -1em; 9 | margin-left: 15em; 10 | text-align: center; 11 | height: 57vh; 12 | display: flex; 13 | flex-direction: column; 14 | justify-content: center; 15 | align-items: center; 16 | } 17 | 18 | h1 { 19 | margin-top: -100px; 20 | font-size: 1.5em; 21 | margin-bottom: 1em; 22 | color: #3c8dbc; 23 | font-weight: normal; 24 | letter-spacing: 0em; 25 | text-shadow: 0px 0px 0px rgba(78, 73, 73, 0.9); 26 | font-family: Arial, Helvetica, sans-serif 27 | } 28 | 29 | @import url('https://fonts.googleapis.com/css?family=Roboto:400,700'); 30 | 31 | body { 32 | font-family: 'Roboto'; 33 | background-color: #1976D2; 34 | } 35 | 36 | form { 37 | max-width: 400px; 38 | background-color: #fff; 39 | margin: 30px auto; 40 | 41 | margin-left: 200px; 42 | padding: 20px; 43 | } 44 | 45 | ul { 46 | list-style: none; 47 | 48 | } 49 | 50 | li:not(:last-child) { 51 | margin-bottom: 5px; 52 | } 53 | 54 | label { 55 | display: flex; 56 | align-items: center; 57 | } 58 | 59 | input[type="radio"] { 60 | margin: 0 10px 0 0; 61 | } 62 | 63 | .title { 64 | font-weight: bold; 65 | font-size: 18px; 66 | } 67 | 68 | .submit-button { 69 | border: 0; 70 | font-family: inherit; 71 | font-size: inherit; 72 | outline: none; 73 | cursor: pointer; 74 | background-color: #7E57C2; 75 | color: #fff; 76 | padding: 10px 30px; 77 | border-radius: 5px; 78 | } 79 | 80 | .submit-button:hover { 81 | background-color: #673AB7; 82 | } 83 | 84 | .submit-button:active { 85 | transform: translateY(1px); 86 | } 87 | .btn_space{ 88 | margin-right:10px; 89 | } 90 | -------------------------------------------------------------------------------- /kafka-backend/services/profile.js: -------------------------------------------------------------------------------- 1 | console.log("in profile service") 2 | 3 | 4 | var User = require("../model/user"); 5 | 6 | function handle_request(msg, callback){ 7 | console.log("In handle request:"+ JSON.stringify(msg)); 8 | console.log("in get profile service") 9 | var email = msg.email; 10 | 11 | User.count({user_email:email}, function (err, count) { 12 | if(err) 13 | { 14 | console.log(message); 15 | res.code="500"; 16 | res.data="Some Error Happened while checking user ID" 17 | callback(null,res); 18 | } 19 | else { 20 | if(count>0) { 21 | console.log("Get profile details"); 22 | 23 | var res = {}; 24 | User.findOne({ 25 | // user_email: req.session.user 26 | user_email: email 27 | }) .select('user_name user_email user_phone user_about_me user_city user_country user_company user_school user_hometown user_language user_gender user_photo') 28 | .exec() 29 | .then(user => { 30 | if (user) { 31 | console.log("record found" + user.user_phone); 32 | console.log("user found" + user); 33 | // res=({user: user, code: "200"}); 34 | res=user 35 | callback(null, res); 36 | //res.status(200).json(user) 37 | }}) 38 | .catch(err => { 39 | console.log("Error case.." + err); 40 | res=({"Message": err, status: "false", code: "500"}); 41 | callback(null, res); 42 | // res.status(500).json({ error: err }) 43 | }) 44 | }} 45 | }) 46 | } 47 | 48 | exports.handle_request = handle_request; 49 | 50 | 51 | -------------------------------------------------------------------------------- /kafka-backend/services/signin.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken") 2 | const bcrypt = require('bcrypt') 3 | 4 | console.log("in signin service") 5 | 6 | var User = require("../model/user"); 7 | 8 | function handle_request(msg, callback){ 9 | console.log("In handle request:"+ JSON.stringify(msg)); 10 | var res = {}; 11 | console.log("signin email:" + msg.user_email ) 12 | 13 | 14 | User.findOne({ 15 | user_email: msg.user_email 16 | }) 17 | .exec() 18 | .then(user => { 19 | if (user) { 20 | console.log("inside first if"+ JSON.stringify(user)); 21 | console.log("user and pwd : " + msg.user_password + user.user_password); 22 | 23 | if (bcrypt.compareSync(msg.user_password, user.user_password)) { 24 | console.log("inside second if ") 25 | //req.session.user = req.body.user_email; 26 | 27 | console.log("after cookie: " + user.user_email + " " + user.user_type) 28 | 29 | var payload={user_email:user.user_email,user_type:user.user_type} 30 | var token = jwt.sign(payload, 'studentuserkey', { 31 | expiresIn: 604800 32 | }) 33 | //res.send(token) 34 | console.log("token sent: " + token); 35 | console.log(" 200 successful login"); 36 | res=({user: token, status: "true", code: "200"}); 37 | callback(null, res); 38 | } else { 39 | console.log("201 Incorrect password"); 40 | res=({user: user, status: "true", code: "201"}); 41 | callback(null, res); 42 | } 43 | 44 | } else { 45 | console.log("203 : user not found"); 46 | res=({code: "203"}); 47 | callback(null, res); 48 | // res.status(203).json({ error: 'User is not registered' }) 49 | } 50 | }) 51 | .catch(err => { 52 | console.log(err); 53 | res=({ code: "500"}); 54 | callback(null, res); 55 | // res.status(500).json({ error: err }) 56 | }) 57 | 58 | } 59 | 60 | exports.handle_request = handle_request; 61 | -------------------------------------------------------------------------------- /frontend/src/components/Pagination.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import "./style.css"; 3 | 4 | class Pagination extends React.Component { 5 | 6 | constructor() { 7 | super(); 8 | this.state = { 9 | todos: ['a','b','c','d','e','f','g','h','i','j','k'], 10 | currentPage: 1, 11 | todosPerPage: 3 12 | }; 13 | this.handleClick = this.handleClick.bind(this); 14 | } 15 | 16 | handleClick(event) { 17 | this.setState({ 18 | currentPage: Number(event.target.id) 19 | }); 20 | } 21 | 22 | render() { 23 | const { todos, currentPage, todosPerPage } = this.state; 24 | 25 | // Logic for displaying current todos 26 | const indexOfLastTodo = currentPage * todosPerPage; 27 | const indexOfFirstTodo = indexOfLastTodo - todosPerPage; 28 | const currentTodos = todos.slice(indexOfFirstTodo, indexOfLastTodo); 29 | 30 | const renderTodos = currentTodos.map((todo, index) => { 31 | return
  • {todo}
  • ; 32 | }); 33 | 34 | // Logic for displaying page numbers 35 | const pageNumbers = []; 36 | for (let i = 1; i <= Math.ceil(todos.length / todosPerPage); i++) { 37 | pageNumbers.push(i); 38 | } 39 | 40 | const renderPageNumbers = pageNumbers.map(number => { 41 | return ( 42 |
  • 47 | {number} 48 |
  • 49 | ); 50 | }); 51 | 52 | return ( 53 |
    54 |
    55 |
    56 |
    57 |
    58 |
    59 |
      60 | {renderTodos} 61 |
    62 |
      63 | {renderPageNumbers} 64 |
    65 |
    66 |
    67 |
    68 |
    69 |
    70 | 71 |
    72 | ); 73 | } 74 | } 75 | export default Pagination -------------------------------------------------------------------------------- /kafka-backend/services/signup.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken") 2 | const bcrypt = require('bcrypt') 3 | 4 | console.log("in signup service") 5 | 6 | var User = require("../model/user"); 7 | 8 | function handle_request(msg, callback){ 9 | console.log("In handle request:"+ JSON.stringify(msg)); 10 | var res = {}; 11 | console.log("signup email:" + msg.user_email ) 12 | 13 | 14 | User.findOne({ user_email: msg.user_email }) 15 | .then(user => { 16 | if (user) { 17 | console.log("user already registered"); 18 | res=({user: user, code: "202"}); 19 | callback(null, res); 20 | // res.status(202).json({ Error: "User already registered"}); 21 | } else { 22 | const newUser = new User({ 23 | // _id: new mongoose.Types.ObjectId(), 24 | user_name: msg.user_name, 25 | user_password: msg.user_password, 26 | user_email: msg.user_email, 27 | user_type: msg.user_type 28 | }) 29 | 30 | bcrypt.genSalt(10, (err, salt) => { 31 | bcrypt.hash(newUser.user_password, salt, (err, hash) => { 32 | if (err) throw err; 33 | newUser.user_password = hash; 34 | newUser 35 | .save() 36 | .then(result => { 37 | console.log("result of query" + result) 38 | res=({user: result, code: "201"}); 39 | callback(null, res); 40 | // res.status(201).json({ message: "creating new user",newUserCreated: result}) 41 | }) 42 | .catch(err => { 43 | console.log("first error" + err); 44 | res=({user: err, code: "500"}); 45 | callback(null, res); 46 | // res.send('error: ' + err) 47 | }) 48 | }); 49 | }); 50 | } 51 | }) 52 | .catch(err => { 53 | console.log("Error case.." + err); 54 | res=({"Message": err, status: "false", code: "500"}); 55 | callback(null, res); 56 | // res.status(500).json({ error: err }) 57 | }) 58 | } 59 | 60 | exports.handle_request = handle_request; 61 | -------------------------------------------------------------------------------- /frontend/src/components/Announce.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import jwt_decode from 'jwt-decode' 3 | import axios from 'axios'; 4 | import {Redirect} from 'react-router'; 5 | import {Link} from 'react-router-dom'; 6 | import "./testcourse.css"; 7 | import ListItem from "./ListItem"; 8 | import _ from "lodash"; 9 | 10 | 11 | 12 | class Announce extends Component { 13 | 14 | constructor() { 15 | super() 16 | this.state = { 17 | courses:[] 18 | } 19 | } 20 | 21 | componentDidMount () { 22 | 23 | axios.get('/studentcourse',{ 24 | user_email: this.state.courses.course_1 25 | }) 26 | .then((response) => { 27 | console.log("printing response" + JSON.stringify(response)) 28 | //update the state with the response data 29 | 30 | this.setState({ 31 | courses : this.state.courses.concat(response.data) 32 | 33 | }); 34 | }) 35 | .catch(err => { 36 | console.log(err) 37 | }) 38 | } 39 | handleOnClick = id => { 40 | const courses = _.cloneDeep(this.state.courses); 41 | 42 | for (let course of courses) { 43 | if (course.id === id) { 44 | //course.completed = !course.completed; 45 | break; 46 | } 47 | } 48 | 49 | this.setState({ courses }); 50 | }; 51 | render() { 52 | const { courses } = this.state; 53 | 54 | return ( 55 |
    56 |
    57 |
    58 |
    59 |
    60 |
    61 |
    62 |

    Courses

    63 |
      64 | {courses.map(chore => ( 65 | 75 | ))} 76 |
    77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |
    85 | ); 86 | } 87 | } 88 | export default Announce; -------------------------------------------------------------------------------- /backend/test.js: -------------------------------------------------------------------------------- 1 | var assert = require('chai').assert; 2 | var app = require('./index'); 3 | var app = require('./routes/users'); 4 | var app = require('./routes/course'); 5 | 6 | var chai = require('chai'); 7 | chai.use(require('chai-http')); 8 | var expect = require('chai').expect; 9 | 10 | var agent = require('chai').request.agent(app); 11 | 12 | console.log("inside test") 13 | describe('get methods', function(){ 14 | 15 | 16 | it('GET /quiz',function(){ 17 | agent.get('/quiz/5ca802e712e6bf7f739000ac') 18 | 19 | // .send(book) 20 | .then(function(res){ 21 | expect(res.body.count).to.equal(1); 22 | }); 23 | }); 24 | 25 | it('GET /assn',function(){ 26 | agent.get('/assn/5cafea6f2986366e9d6da9a9') 27 | 28 | // .send(book) 29 | .then(function(res){ 30 | expect(res.body.count).to.equal(1); 31 | }); 32 | }); 33 | }) 34 | /* 35 | 36 | it('POST /signin',function(){ 37 | agent.post('/signin') 38 | 39 | 40 | send( { 41 | "user_email": "rakhee@gmail.com", 42 | "user_password": "rakhee" 43 | }) 44 | // .then(function(res){ 45 | 46 | .expect(200) 47 | // .expect('Content-Type', /json/) 48 | .expect(res.body.count).to.equal(1); 49 | }); 50 | }); 51 | 52 | 53 | */ 54 | 55 | /* 56 | let mongoose = require("mongoose"); 57 | //let Book = require('../app/models/book'); 58 | 59 | let chai = require('chai'); 60 | let chaiHttp = require('chai-http'); 61 | //let server = require('../server'); 62 | let should = chai.should(); 63 | var server = require('./routes/users'); 64 | 65 | chai.use(chaiHttp); 66 | 67 | describe('/POST book', () => { 68 | it('it should not POST a book without pages field', (done) => { 69 | let book = { 70 | "user_email": "rakhee@gmail.com", 71 | "user_password": "rakhee" 72 | } 73 | chai.request(server) 74 | .post('/signin') 75 | .send(book) 76 | .end((err, res) => { 77 | res.should.have.status(200); 78 | res.body.should.be.a('object'); 79 | // res.body.should.have.property('errors'); 80 | // res.body.errors.should.have.property('pages'); 81 | // res.body.errors.pages.should.have.property('kind').eql('required'); 82 | done(); 83 | }); 84 | }); 85 | 86 | }); 87 | */ 88 | -------------------------------------------------------------------------------- /frontend/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /kafka-backend/services/coursedetails.js: -------------------------------------------------------------------------------- 1 | console.log("in course details") 2 | 3 | 4 | var User = require("../model/user"); 5 | var Course = require("../model/course"); 6 | 7 | function handle_request(msg, callback){ 8 | console.log("In handle request:"+ JSON.stringify(msg)); 9 | 10 | var email = msg.email; 11 | var course_id = msg.course_id 12 | /* 13 | User.count({user_email:email}, function (err, count) { 14 | if(err) 15 | { 16 | console.log(message); 17 | res.code="500"; 18 | res.data="Some Error Happened while checking user ID" 19 | callback(null,res); 20 | } 21 | else { 22 | if(count>0) { 23 | console.log("Get profile details"); 24 | */ 25 | var res = []; 26 | Course.findOne({ 27 | // user_email: req.session.user 28 | course_id: course_id 29 | }) .select('course_id course_name course_dep course_desc course_room course_cap course_wl_cap course_term course_enrollment_count course_wl_count') 30 | .exec() 31 | .then(course => { 32 | if (course) { 33 | console.log("record found" + course.course_name); 34 | console.log("user found" + course); 35 | // res=({user: user, status: "true", code: "200"}); 36 | 37 | var retFields = [] 38 | retFields.push({"course_id": course.course_id, 39 | "course_name": course.course_name, 40 | "course_dep": course.course_dep, 41 | "course_desc": course.course_desc, 42 | "course_room": course.course_room, 43 | "course_cap": course.course_cap, 44 | "course_wl_cap": course.course_wl_cap, 45 | "course_term": course.course_term, 46 | "course_enrollment_count": course.course_enrollment_count, 47 | "course_wl_count": course.course_wl_count 48 | }); 49 | res=retFields 50 | callback(null, res); 51 | //res.status(200).json(user) 52 | }}) 53 | .catch(err => { 54 | console.log("Error case.." + err); 55 | res=({"Message": err, status: "false", code: "500"}); 56 | callback(null, res); 57 | // res.status(500).json({ error: err }) 58 | }) 59 | // }} 60 | // }) 61 | } 62 | 63 | exports.handle_request = handle_request; 64 | 65 | 66 | -------------------------------------------------------------------------------- /frontend/src/components/ViewSub.js: -------------------------------------------------------------------------------- 1 | // MyApp.js 2 | import React, { Component } from 'react'; 3 | //import logger from 'logging-library'; 4 | import FileViewer from 'react-file-viewer'; 5 | import { CustomErrorComponent } from 'custom-error'; 6 | import axios from 'axios'; 7 | 8 | const file ='http://localhost:3001/profile_uploads/2019-04-16T00:52:14.228ZeStmt_2019-02-08.pdf' 9 | const type = 'pdf' 10 | 11 | class ViewSub extends Component { 12 | constructor(props) { 13 | super(props); 14 | this.state = { 15 | // assn_id:'', 16 | // user_email:'', 17 | assn_rec:[], 18 | rescode:0 19 | } 20 | 21 | } 22 | 23 | componentDidMount(){ 24 | console.log("params " + JSON.stringify(this.props.match.params)) 25 | 26 | const { user_email,assn_id } = this.props.match.params 27 | /* 28 | this.setState({ 29 | assn_id : assn_id,user_email: user_email 30 | }); 31 | console.log("assn id: " + JSON.stringify(this.state.ass_id)) 32 | console.log("user email: " + JSON.stringify(this.state.user_email)) 33 | */ 34 | 35 | console.log("assn id: " + assn_id) 36 | console.log("user email: " + user_email) 37 | axios.get('http://localhost:3001/users/path' 38 | ,{ 39 | params:{assn_id: assn_id,user_email:user_email}} 40 | ) 41 | .then((response) => { 42 | console.log("response: " + JSON.stringify(response.data)) 43 | 44 | //update the state with the response data 45 | 46 | this.setState({ 47 | assn_rec : response.data 48 | 49 | }); 50 | 51 | if(response){ 52 | this.setState({ 53 | rescode: 200 54 | 55 | }); 56 | } 57 | console.log("path " + JSON.stringify(this.state.assn_rec.user_file)) 58 | console.log("path1" + this.state.assn_rec.user_file) 59 | }) 60 | .catch(err => { 61 | console.log(err) 62 | }) 63 | } 64 | render() { 65 | 66 | console.log("filename1 " +this.state.assn_rec.user_file) 67 | console.log("filename2 " + JSON.stringify(this.state.assn_rec.user_file)) 68 | var file = '' 69 | // file = 'http://localhost:3001/'+`${this.state.assn_rec.user_file}` 70 | file = this.state.assn_rec.user_file 71 | console.log("filename a " + file) 72 | let newfile ='' 73 | newfile = file 74 | console.log("filename b " + newfile) 75 | return ( 76 | 81 | ); 82 | } 83 | 84 | 85 | } 86 | export default ViewSub; -------------------------------------------------------------------------------- /frontend/src/components/ToggleMenu.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Button from '@material-ui/core/Button'; 4 | import ClickAwayListener from '@material-ui/core/ClickAwayListener'; 5 | import Grow from '@material-ui/core/Grow'; 6 | import Paper from '@material-ui/core/Paper'; 7 | import Popper from '@material-ui/core/Popper'; 8 | import MenuItem from '@material-ui/core/MenuItem'; 9 | import MenuList from '@material-ui/core/MenuList'; 10 | import { withStyles } from '@material-ui/core/styles'; 11 | 12 | const styles = theme => ({ 13 | root: { 14 | display: 'flex', 15 | }, 16 | paper: { 17 | marginRight: theme.spacing.unit * 2, 18 | }, 19 | }); 20 | 21 | class MenuListComposition extends React.Component { 22 | state = { 23 | open: false, 24 | }; 25 | 26 | handleToggle = () => { 27 | this.setState(state => ({ open: !state.open })); 28 | }; 29 | 30 | handleClose = event => { 31 | if (this.anchorEl.contains(event.target)) { 32 | return; 33 | } 34 | 35 | this.setState({ open: false }); 36 | }; 37 | 38 | render() { 39 | const { classes } = this.props; 40 | const { open } = this.state; 41 | 42 | return ( 43 |
    44 | 45 | 46 | Profile 47 | My account 48 | Logout 49 | 50 | 51 |
    52 | 62 | 63 | {({ TransitionProps, placement }) => ( 64 | 69 | 70 | 71 | 72 | Profile 73 | My account 74 | Logout 75 | 76 | 77 | 78 | 79 | )} 80 | 81 |
    82 |
    83 | ); 84 | } 85 | } 86 | 87 | MenuListComposition.propTypes = { 88 | classes: PropTypes.object.isRequired, 89 | }; 90 | 91 | export default withStyles(styles)(MenuListComposition); -------------------------------------------------------------------------------- /frontend/src/components/UpdatePhoto.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | //import { updateProfile } from './myfunctions'; 3 | import {Redirect} from 'react-router'; 4 | import cookie from 'react-cookies'; 5 | import Button from '@material-ui/core/Button'; 6 | import axios from 'axios'; 7 | 8 | class UpdateProfile extends Component { 9 | constructor() { 10 | super() 11 | this.state = { 12 | user_photo: null 13 | } 14 | 15 | // this.onChange = this.onChange.bind(this) 16 | this.onChange1 = this.onChange1.bind(this) 17 | this.onSubmit = this.onSubmit.bind(this) 18 | } 19 | 20 | 21 | onChange1 (e) { 22 | this.setState({user_photo: e.target.files[0]}); 23 | } 24 | 25 | onSubmit (e) { 26 | 27 | 28 | const formData = new FormData(); 29 | formData.append('user_photo', this.state.user_photo); 30 | 31 | const config = { 32 | headers: { 33 | 'content-type': 'multipart/form-data' 34 | } 35 | }; 36 | e.preventDefault() 37 | axios.post('/users/photoupdate',formData,config) 38 | .then((response) => { 39 | alert("The photo is successfully uploaded"); 40 | console.log("printing response" + JSON.stringify(response)) 41 | 42 | this.props.history.push('/') 43 | }) 44 | .catch(err => { 45 | console.log(err) 46 | }) 47 | } 48 | 49 | 50 | render () { 51 | let redirectVar = null; 52 | if(!cookie.load('cookie')){ 53 | redirectVar = 54 | } 55 | return ( 56 |
    57 | {redirectVar} 58 |
    59 |
    60 |
    61 |
    62 |
    63 |

    Upload/Change Photo

    64 | 65 |
    66 | 67 | 68 |
    69 | 70 | 74 | 75 |
    76 |
    80 |
    81 |
    82 |
    83 |
    84 |
    85 |
    86 | ) 87 | } 88 | } 89 | 90 | export default UpdateProfile -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | body > #root > div { 4 | height: 100vh; 5 | } 6 | .content-wrapper { 7 | height: 170vh; 8 | } 9 | 10 | .btnDiv { 11 | width: 100%; 12 | left: 300px; 13 | top: 10px; 14 | position: absolute; 15 | } 16 | .container { 17 | width: 100%; 18 | } 19 | .left, .right { 20 | width: 50%; 21 | float: left; 22 | } 23 | .fieldBlock 24 | { 25 | height: 500px; 26 | display: block; 27 | background-color:white; 28 | width: 220px; 29 | margin-bottom: 700px; 30 | float: left; 31 | padding: 10px 0px 10px 10px; 32 | border-style: solid; 33 | border-color: rgb(248, 248, 248); 34 | border-width: 0.2px; 35 | } 36 | 37 | .title 38 | { 39 | font-weight: 400; 40 | font-family: "Lucida Console"; 41 | border-style: solid; 42 | border-color: rgb(248, 248, 248); 43 | background-color:white; 44 | border-width: 0.2px; 45 | padding: 0.5em 46 | } 47 | img { 48 | display: block; 49 | max-width:230px; 50 | max-height:95px; 51 | width: auto; 52 | height: auto; 53 | } 54 | input 55 | { 56 | border: 1px solid rgb(217, 225, 228); 57 | font-size: 1.1em; 58 | } 59 | /* 60 | table, td, th { 61 | border: 1px solid #ddd; 62 | text-align: left; 63 | } 64 | 65 | th,td {padding: 15px; 66 | } 67 | */ 68 | table { 69 | border-collapse: collapse; 70 | width: 820px; 71 | position: absolute; 72 | top:50px; 73 | left:-50px 74 | } 75 | 76 | table td, table th { 77 | border: 1px solid #ddd; 78 | padding: 8px; 79 | } 80 | 81 | table tr:nth-child(even){background-color: #ffffff;} 82 | table tr:nth-child(odd){background-color: #ddd} 83 | 84 | table tr:hover {background-color: #91b8d88c;;} 85 | 86 | table th { 87 | padding-top: 12px; 88 | padding-bottom: 12px; 89 | text-align: left; 90 | /* background-color: rgb(126, 128, 138); */ 91 | background-color: #3c8dbc; 92 | color: white; 93 | } 94 | 95 | #btn_space{ 96 | margin-right:10px; 97 | } 98 | 99 | form input.error { 100 | border-color: red; 101 | } 102 | 103 | /* 104 | body { 105 | background-color: #FFCC00; 106 | padding: 20px; 107 | margin: 0; 108 | } 109 | h1, h2, p, Nav, NavItem { 110 | font-family: sans-serif; 111 | } 112 | 113 | Nav.header NavItem { 114 | display: inline; 115 | list-style-type: none; 116 | margin: 0; 117 | } 118 | 119 | Nav.header { 120 | background-color: #111; 121 | padding: 0; 122 | } 123 | Nav.header NavItem { 124 | color: #FFF; 125 | font-weight: bold; 126 | text-decoration: none; 127 | padding: 20px; 128 | display: inline-block; 129 | } 130 | .content { 131 | background-color: #FFF; 132 | padding: 20px; 133 | } 134 | .content h2 { 135 | padding: 0; 136 | margin: 0; 137 | } 138 | .content NavItem { 139 | margin-bottom: 10px; 140 | } 141 | 142 | .active { 143 | background-color: #0099FF; 144 | } 145 | */ -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `npm start` 8 | 9 | Runs the app in the development mode.
    10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
    13 | You will also see any lint errors in the console. 14 | 15 | ### `npm test` 16 | 17 | Launches the test runner in the interactive watch mode.
    18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `npm run build` 21 | 22 | Builds the app for production to the `build` folder.
    23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
    26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `npm run eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `npm run build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /frontend/src/components/Header.js: -------------------------------------------------------------------------------- 1 | // Header.js 2 | import React, {Component} from 'react'; 3 | import {Link} from 'react-router-dom'; 4 | 5 | export default class Header extends Component { 6 | render(){ 7 | return ( 8 |
    9 | 10 | SJSU 11 | SJSU 12 | 13 | 51 |
    52 | ) 53 | } 54 | } -------------------------------------------------------------------------------- /frontend/src/actions/userActions.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const SIGN_IN = 'SIGN_IN'; 4 | export const SIGN_UP = 'SIGN_UP'; 5 | export const FETCH_PROFILE = 'FETCH_PROFILE'; 6 | export const UPDATE_PROF = 'UPDATE_PROF'; 7 | 8 | const ROOT_URL = "/users"; 9 | 10 | var accessToken = localStorage.getItem('usertoken') 11 | 12 | 13 | 14 | // Set the AUTH token for any request 15 | axios.interceptors.request.use(function (config) { 16 | const token = localStorage.getItem('usertoken'); 17 | config.headers.Authorization = token ? `Bearer ${token}` : ''; 18 | return config; 19 | }); 20 | 21 | 22 | 23 | export const fetchProfile = () => dispatch => { 24 | // let accessToken = localStorage.getItem('usertoken') 25 | console.log("accessToken: " + accessToken) 26 | axios.get(`${ROOT_URL}/profile`) 27 | .then(responseData => 28 | dispatch({ 29 | type: FETCH_PROFILE, 30 | payload: responseData 31 | }) 32 | 33 | ); 34 | }; 35 | 36 | export const signUp = (values,callback) => dispatch => { 37 | axios.post(`${ROOT_URL}/signup`, values) 38 | .then(response => 39 | dispatch({ 40 | type: SIGN_UP, 41 | payload: response.status 42 | }) 43 | ) 44 | .then(() => callback()); 45 | 46 | }; 47 | 48 | export const updateProfile = (values,callback) => dispatch => { 49 | console.log("accessToken: " + accessToken) 50 | // axios.post(`${ROOT_URL}/profileupdate`,values,{headers:{'Content-Type': 'application/json','Authorization': `Bearer ${accessToken}`}},callback) 51 | axios.post(`${ROOT_URL}/profile`,values,callback) 52 | .then(response =>{ 53 | console.log("response status in updprf action : " + response.status + JSON.stringify(response.data)) 54 | dispatch({ 55 | type: UPDATE_PROF, 56 | payload: response.status 57 | })} 58 | ) 59 | .then(() => callback()); 60 | 61 | }; 62 | 63 | export const signin = (values,callback) => dispatch => { 64 | //set the with credentials to true 65 | axios.defaults.withCredentials = true; 66 | axios.post(`${ROOT_URL}/signin`,values) 67 | .then(response => { 68 | localStorage.setItem('usertoken', response.data) 69 | console.log("response status in action : " + response.status + response.data) 70 | dispatch({ 71 | type: SIGN_IN, 72 | payload: response.status 73 | })} 74 | ) 75 | .then(() => callback()); 76 | }; 77 | 78 | 79 | /* 80 | export function fetchProfile() { 81 | //middleware call 82 | //receive response from backend 83 | const response = axios.get(`${ROOT_URL}/profileget`); 84 | //Action dispatched 85 | console.log("Response",response); 86 | return { 87 | type: FETCH_PROFILE, 88 | payload: response 89 | }; 90 | } 91 | */ 92 | /* 93 | export function updateProfile(values, callback) { 94 | const request = axios 95 | .post(`${ROOT_URL}/updateProfile`, values) 96 | .then(() => callback()); 97 | 98 | return { 99 | type: UPD_PROFILE, 100 | payload: request 101 | }; 102 | } 103 | */ -------------------------------------------------------------------------------- /backend/kafka/kafkarpc.js: -------------------------------------------------------------------------------- 1 | var crypto = require('crypto'); 2 | var conn = require('./connection'); 3 | 4 | var TIMEOUT=8000; //time to wait for response in ms 5 | var self; 6 | 7 | exports = module.exports = KafkaRPC; 8 | 9 | function KafkaRPC(){ 10 | self = this; 11 | this.connection = conn; 12 | this.requests = {}; //hash to store request in wait for response 13 | this.response_queue = false; //placeholder for the future queue 14 | this.producer = this.connection.getProducer(); 15 | } 16 | 17 | KafkaRPC.prototype.makeRequest = function(topic_name, content, callback){ 18 | 19 | self = this; 20 | //generate a unique correlation id for this call 21 | var correlationId = crypto.randomBytes(16).toString('hex'); 22 | 23 | //create a timeout for what should happen if we don't get a response 24 | var tId = setTimeout(function(corr_id){ 25 | //if this ever gets called we didn't get a response in a 26 | //timely fashion 27 | console.log('timeout'); 28 | callback(new Error("timeout " + corr_id)); 29 | //delete the entry from hash 30 | delete self.requests[corr_id]; 31 | }, TIMEOUT, correlationId); 32 | 33 | //create a request entry to store in a hash 34 | var entry = { 35 | callback:callback, 36 | timeout: tId //the id for the timeout so we can clear it 37 | }; 38 | 39 | //put the entry in the hash so we can match the response later 40 | self.requests[correlationId]=entry; 41 | 42 | //make sure we have a response topic 43 | self.setupResponseQueue(self.producer,topic_name,function(){ 44 | console.log('in response'); 45 | //put the request on a topic 46 | 47 | var payloads = [ 48 | { topic: topic_name, messages: JSON.stringify({ 49 | correlationId:correlationId, 50 | replyTo:'response_topic', 51 | data:content}), 52 | partition:0} 53 | ]; 54 | console.log('in response1'); 55 | console.log(self.producer.ready); 56 | self.producer.send(payloads, function(err, data){ 57 | console.log('in response2'); 58 | if(err) 59 | console.log(err); 60 | console.log(data); 61 | }); 62 | }); 63 | }; 64 | 65 | 66 | KafkaRPC.prototype.setupResponseQueue = function(producer,topic_name, next){ 67 | //don't mess around if we have a queue 68 | if(this.response_queue) return next(); 69 | 70 | console.log('1'); 71 | 72 | self = this; 73 | 74 | //subscribe to messages 75 | var consumer = self.connection.getConsumer('response_topic'); 76 | consumer.on('message', function (message) { 77 | console.log('msg received'); 78 | var data = JSON.parse(message.value); 79 | //get the correlationId 80 | var correlationId = data.correlationId; 81 | //is it a response to a pending request 82 | if(correlationId in self.requests){ 83 | //retrieve the request entry 84 | var entry = self.requests[correlationId]; 85 | //make sure we don't timeout by clearing it 86 | clearTimeout(entry.timeout); 87 | //delete the entry from hash 88 | delete self.requests[correlationId]; 89 | //callback, no err 90 | entry.callback(null, data.data); 91 | } 92 | }); 93 | self.response_queue = true; 94 | console.log('returning next'); 95 | return next(); 96 | }; -------------------------------------------------------------------------------- /frontend/src/components/GradeAssignment.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import React, { Component } from 'react'; 3 | import {Link} from 'react-router-dom'; 4 | 5 | 6 | class GradeAssignment extends Component { 7 | 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | 12 | assns: [], 13 | position: 0, 14 | student_answers: [], 15 | ischecked: false, 16 | course_id:'', 17 | quiz_id: '', 18 | rescode:0 19 | } 20 | 21 | } 22 | 23 | componentDidMount(){ 24 | console.log("params " + JSON.stringify(this.props.match.params)) 25 | // const { quiz_id } = this.props.match.params 26 | const { course_id } = this.props.match.params 27 | 28 | this.setState({course_id: course_id}) 29 | 30 | console.log("course_id2 :" + this.state.course_id ) 31 | 32 | axios.get('/course/subassigns',{ 33 | params:{course_id: course_id} 34 | }) 35 | .then((response) => { 36 | console.log("submitted assignments: " + JSON.stringify(response)) 37 | 38 | this.setState({ 39 | assns : (response.data).slice(0) 40 | 41 | }); 42 | 43 | 44 | 45 | if(response){ 46 | this.setState({ 47 | rescode: 200 48 | 49 | }); 50 | } 51 | }) 52 | .catch(err => { 53 | console.log(err) 54 | }) 55 | } 56 | 57 | 58 | render(){ 59 | 60 | 61 | let det = this.state.assns.map(assn => { 62 | 63 | return( 64 | 65 | 66 | 67 | {/* */} 68 | {assn.user_email} 69 | {assn.title} 70 | {assn.submitted_on} 71 | {/* {assn.user_file}*/} 72 | {assn.user_file} 73 | View 74 | Enter Grade 75 | {assn.total_points} 76 | 77 | 78 | ) 79 | 80 | }) 81 | 82 | return ( 83 |
    84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | {det} 104 | 105 |
    Student IdAssignment TitleSubmitted OnDownload SubmissionView SubmissionGradingTotal Points
    106 |
    107 |
    108 |
    109 |
    110 |
    111 |
    112 |
    113 | ) 114 | } 115 | 116 | } 117 | 118 | export default GradeAssignment 119 | 120 | -------------------------------------------------------------------------------- /kafka-backend/server.js: -------------------------------------------------------------------------------- 1 | var connection = new require('./kafka/Connection'); 2 | //topics files 3 | var Profilepic = require('./services/profilepic.js'); 4 | var Signup = require('./services/signup.js'); 5 | var Signin = require('./services/signin.js'); 6 | var MessageList = require('./services/messagelist.js'); 7 | var CourseDetails = require('./services/coursedetails.js'); 8 | var Profile = require('./services/profile.js'); 9 | var UpdateProfile = require('./services/updateprofile.js'); 10 | var MsgBySubject = require('./services/msgBySubject.js'); 11 | var Replytomsg = require('./services/replytomsg.js'); 12 | var GetCourses = require('./services/get_courses.js'); 13 | var AddCourse = require('./services/addcourse.js'); 14 | var Announcement = require('./services/announcement.js'); 15 | var Assignment = require('./services/assignment.js'); 16 | var GetAnnouncements = require('./services/getAnnouncements.js'); 17 | var GetAssignments = require('./services/getAssignments.js'); 18 | var GetAssignmentById = require('./services/getAssignmentById.js'); 19 | var GetQuizById = require('./services/getQuizById.js'); 20 | var SubAssigns = require('./services/subassigns.js'); 21 | var GetLectures = require('./services/getLectures.js'); 22 | var CheckUserCourse = require('./services/checkusercourse.js'); 23 | var RemoveStudent = require('./services/removestudent.js'); 24 | 25 | function handleTopicRequest(topic_name,fname){ 26 | //var topic_name = 'root_topic'; 27 | var consumer = connection.getConsumer(topic_name); 28 | var producer = connection.getProducer(); 29 | console.log('server is running '); 30 | consumer.on('message', function (message) { 31 | console.log('message received for ' + topic_name +" ", fname); 32 | console.log(JSON.stringify(message.value)); 33 | var data = JSON.parse(message.value); 34 | 35 | fname.handle_request(data.data, function(err,res){ 36 | console.log('after handle'+res); 37 | var payloads = [ 38 | { topic: data.replyTo, 39 | messages:JSON.stringify({ 40 | correlationId:data.correlationId, 41 | data : res 42 | }), 43 | partition : 0 44 | } 45 | ]; 46 | producer.send(payloads, function(err, data){ 47 | console.log(data); 48 | }); 49 | return; 50 | }); 51 | 52 | }); 53 | } 54 | // Add your TOPICs here 55 | //first argument is topic name 56 | //second argument is a function that will handle this topic request 57 | //handleTopicRequest("post_book",Books) 58 | handleTopicRequest("get_courses",GetCourses) 59 | handleTopicRequest("coursedetails",CourseDetails) 60 | handleTopicRequest("profile",Profile) 61 | handleTopicRequest("updateprofile",UpdateProfile) 62 | handleTopicRequest("messagelist",MessageList) 63 | handleTopicRequest("msgBySubject",MsgBySubject) 64 | handleTopicRequest("replytomsg",Replytomsg) 65 | handleTopicRequest("signin",Signin) 66 | handleTopicRequest("signup",Signup) 67 | handleTopicRequest("profilepic",Profilepic) 68 | handleTopicRequest("addcourse",AddCourse) 69 | handleTopicRequest("announcement",Announcement) 70 | handleTopicRequest("assignment",Assignment) 71 | handleTopicRequest("getAnnouncements",GetAnnouncements) 72 | handleTopicRequest("getAssignments",GetAssignments) 73 | handleTopicRequest("getAssignmentById",GetAssignmentById) 74 | handleTopicRequest("getQuizById",GetQuizById) 75 | handleTopicRequest("subassigns",SubAssigns) 76 | handleTopicRequest("getLectures",GetLectures) 77 | handleTopicRequest("checkusercourse",CheckUserCourse) 78 | handleTopicRequest("removestudent",RemoveStudent) -------------------------------------------------------------------------------- /frontend/src/components/GradeEntry.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import React, { Component } from 'react'; 3 | import {Link} from 'react-router-dom'; 4 | 5 | 6 | class GradeEntry extends Component { 7 | 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | 12 | assns: [], 13 | user_grade:0, 14 | total_points: 0, 15 | student_answers: [], 16 | ischecked: false, 17 | assn_id:'', 18 | task_id:'', 19 | course_id:'', 20 | user_email:'', 21 | rescode:0, 22 | title:'' 23 | } 24 | this.onChange = this.onChange.bind(this); 25 | this.onSubmit = this.onSubmit.bind(this); 26 | } 27 | 28 | onChange(e) { 29 | this.setState({ [e.target.name]: e.target.value }) 30 | } 31 | 32 | componentDidMount(){ 33 | console.log("params " + JSON.stringify(this.props.match.params)) 34 | // const { quiz_id } = this.props.match.params 35 | const { assn_id } = this.props.match.params 36 | // const { total_points } = this.props.match.params 37 | const { title } = this.props.match.params 38 | const { course_id } = this.props.match.params 39 | const { user_email} = this.props.match.params 40 | const { total_points} = this.props.match.params 41 | console.log("points: " + total_points + "email :" + user_email) 42 | 43 | this.setState({assn_id: assn_id, course_id: course_id,user_email:user_email, 44 | title:title,total_points:total_points}) 45 | } 46 | 47 | onSubmit(e){ 48 | // console.log("course_id2 :" + this.state.course_id ) 49 | e.preventDefault() 50 | 51 | axios.post('/course/assngrade',{ 52 | // task_outof: this.state.assn.total_points, 53 | task_title:this.state.title,course_id:this.state.course_id,user_email:this.state.user_email, 54 | task_id: this.state.assn_id,task_grade:this.state.user_grade,task_outof:this.state.total_points 55 | 56 | }) 57 | .then((response) => { 58 | console.log("grade entry response: " + JSON.stringify(response)) 59 | 60 | if (response.status==201) 61 | this.setState({rescode: 201}) 62 | }) 63 | .catch(err => { 64 | console.log(err) 65 | }) 66 | } 67 | 68 | render(){ 69 | let det ='' 70 | if(this.state.rescode==201) 71 | det =
    Grade Submitted!
    72 | 73 | return ( 74 |
    75 |
    76 |
    77 |
    78 |
    79 |
    80 |

    Grading Assignment

    81 |
    82 | 83 | 90 |
    91 | 92 | 96 | {det} 97 |
    98 |
    99 |
    100 |
    101 |
    102 |
    103 | ) 104 | } 105 | 106 | } 107 | 108 | export default GradeEntry 109 | 110 | -------------------------------------------------------------------------------- /frontend/src/components/Main.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {Route,Switch} from 'react-router-dom'; 3 | import Signin from './Signin'; 4 | import Signup from './Signup'; 5 | import Home from './Home'; 6 | import DispProfile from './DispProfile'; 7 | import UpdateProfile from './UpdateProfile'; 8 | import UpdatePhoto from './UpdatePhoto'; 9 | import Dashboard from './Dashboard'; 10 | import Search from './Search'; 11 | import EnrollCourse from './EnrollCourse'; 12 | import DropCourse from './DropCourse'; 13 | import CreateCourse from './CreateCourse'; 14 | import GenCode from './GenCode'; 15 | import CourseMenu from './CourseMenu'; 16 | import Assignment from './Assignment'; 17 | import Quiz from './Quiz/Quiz'; 18 | import Inbox from './Inbox/Inbox'; 19 | import Messages from './Inbox/Messages'; 20 | import NewMessage from './Inbox/NewMessage'; 21 | import AddQuestion from './Quiz/AddQuestion'; 22 | import GradeAssignment from './GradeAssignment'; 23 | import GradeEntry from './GradeEntry'; 24 | import SubmissionViewer from './SubmissionViewer'; 25 | import ViewSub from './ViewSub'; 26 | 27 | 28 | //Create a Main Component 29 | class Main extends Component { 30 | render(){ 31 | return( 32 |
    33 | {/*Render Different Component based on Route*/} 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {/* } /> */} 59 | {/* */} 60 | } /> 61 | } /> 62 | } /> 63 | } /> 64 | } /> 65 | } /> 66 | } /> 67 | } /> 68 |
    69 | ) 70 | 71 | } 72 | } 73 | //Export The Main Component 74 | export default Main; -------------------------------------------------------------------------------- /frontend/src/components/myfunctions.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | 4 | export const crtAnc = newAnc => { 5 | return axios 6 | .post('/course/announcement', { 7 | course_id: newAnc.course_id, 8 | title: newAnc.title, 9 | content: newAnc.content 10 | }) 11 | .then(data => console.log(data)) //for checking response that was sent back from post mthod signup 12 | .catch(err => console.log(err)) 13 | } 14 | 15 | 16 | 17 | export const crtQuiz = newQuiz => { 18 | return axios 19 | .post('/course/createquiz', { 20 | course_id: newQuiz.course_id, 21 | title: newQuiz.title, 22 | question: newQuiz.question, 23 | optionA: newQuiz.optionA, 24 | optionB: newQuiz.optionB, 25 | optionC: newQuiz.optionC, 26 | optionD: newQuiz.optionD, 27 | answer: newQuiz.answer, 28 | due_date: newQuiz.due_date 29 | }) 30 | .then(data => console.log(data)) //for checking response that was sent back from post mthod signup 31 | .catch(err => console.log(err)) 32 | } 33 | 34 | 35 | export const createCourse = newCourse => { 36 | return axios 37 | .post('/course/coursecreate', { 38 | course_id: newCourse.course_id, 39 | course_dep: newCourse.course_dep, 40 | course_name: newCourse.course_name, 41 | course_term: newCourse.course_term, 42 | course_desc: newCourse.course_desc, 43 | course_room: newCourse.course_room, 44 | course_cap: newCourse.course_cap, 45 | course_wl_cap: newCourse.course_wl_cap 46 | 47 | }) 48 | .then(data => console.log(data)) //for checking response that was sent back from post mthod signup 49 | .catch(err => console.log(err)) 50 | } 51 | 52 | /* 53 | export const updateProfile = userProf => { 54 | 55 | return axios 56 | .post('/profileupdate',formData,config) 57 | 58 | // user_name: userProf.user_name, 59 | // user_email: userProf.user_email, 60 | // user_phone: userProf.user_phone, 61 | // user_about_me: userProf.user_about_me, 62 | // user_city: userProf.user_city, 63 | // user_country: userProf.user_country, 64 | // user_company: userProf.user_company, 65 | // user_school: userProf.user_school, 66 | // user_hometown: userProf.user_hometown, 67 | // user_language: userProf.user_language, 68 | // user_gender: userProf.user_gender, 69 | // user_photo: userProf.user_photo 70 | // }) 71 | .then(data => console.log("printing response" + JSON.stringify(data))) //for checking response that was sent back from post mthod signup 72 | .catch(err => console.log(err)) 73 | } 74 | 75 | */ 76 | export const signin = user => { 77 | return axios 78 | .post('/signin', { 79 | user_email: user.user_email, 80 | user_password: user.user_password 81 | }) 82 | .then(res => { 83 | localStorage.setItem('usertoken', res.data) 84 | return res.data 85 | }) 86 | .then(data => console.log(data)) 87 | .catch(err => { 88 | console.log(err) 89 | }) 90 | } 91 | 92 | export const enroll = course => { 93 | return axios 94 | .post('/courseenrollment', { 95 | course_id: course.course_id 96 | }) 97 | .then(response => { 98 | console.log("printing response" + JSON.stringify(response)) 99 | }) 100 | 101 | .catch(err => console.log(err)) 102 | } 103 | 104 | export const drop = course => { 105 | return axios 106 | .post('/courseenrollment', { 107 | course_id: course.course_id 108 | }) 109 | .then(data => console.log(data)) 110 | .catch(err => console.log(err)) 111 | } 112 | 113 | 114 | -------------------------------------------------------------------------------- /frontend/public/js/jquery.slimscroll.min.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) 2 | * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 3 | * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 4 | * 5 | * Version: 1.3.1 6 | * 7 | */ 8 | (function(f){jQuery.fn.extend({slimScroll:function(h){var a=f.extend({width:"auto",height:"550px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:0.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:0.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},h);this.each(function(){function r(d){if(s){d=d|| 9 | window.event;var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);f(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&m(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function m(d,f,h){k=!1;var e=d,g=b.outerHeight()-c.outerHeight();f&&(e=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),e=Math.min(Math.max(e,0),g),e=0=b.outerHeight()?k=!0:(c.stop(!0,!0).fadeIn("fast"),a.railVisible&&g.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(A=setTimeout(function(){a.disableFadeOut&&s||(x||y)||(c.fadeOut("slow"),g.fadeOut("slow"))},1E3))}var s,x,y,A,z,u,l,B,D=30,k=!1,b=f(this);if(b.parent().hasClass(a.wrapperClass)){var n=b.scrollTop(), 12 | c=b.parent().find("."+a.barClass),g=b.parent().find("."+a.railClass);w();if(f.isPlainObject(h)){if("height"in h&&"auto"==h.height){b.parent().css("height","auto");b.css("height","auto");var q=b.parent().parent().height();b.parent().css("height",q);b.css("height",q)}if("scrollTo"in h)n=parseInt(a.scrollTo);else if("scrollBy"in h)n+=parseInt(a.scrollBy);else if("destroy"in h){c.remove();g.remove();b.unwrap();return}m(n,!1,!0)}}else{a.height="auto"==a.height?b.parent().height():a.height;n=f("
    ").addClass(a.wrapperClass).css({position:"relative", 13 | overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden",width:a.width,height:a.height});var g=f("
    ").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=f("
    ").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible? 14 | "block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius,WebkitBorderRadius:a.borderRadius,zIndex:99}),q="right"==a.position?{right:a.distance}:{left:a.distance};g.css(q);c.css(q);b.wrap(n);b.parent().append(c);b.parent().append(g);a.railDraggable&&c.bind("mousedown",function(a){var b=f(document);y=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);m(0,c.position().top,!1)}); 15 | b.bind("mouseup.slimscroll",function(a){y=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll",function(a){a.stopPropagation();a.preventDefault();return!1});g.hover(function(){v()},function(){p()});c.hover(function(){x=!0},function(){x=!1});b.hover(function(){s=!0;v();p()},function(){s=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(z=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&& 16 | (m((z-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),z=b.originalEvent.touches[0].pageY)});w();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),m(0,!0)):"top"!==a.start&&(m(f(a.start).position().top,null,!0),a.alwaysVisible||c.hide());C()}});return this}});jQuery.fn.extend({slimscroll:jQuery.fn.slimScroll})})(jQuery); -------------------------------------------------------------------------------- /frontend/src/components/Inbox/Inbox.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import axios from 'axios'; 3 | import cookie from 'react-cookies'; 4 | import {Redirect} from 'react-router'; 5 | import io from 'socket.io-client'; 6 | import {Link} from 'react-router-dom'; 7 | 8 | //var socket = io() 9 | 10 | class Inbox extends Component { 11 | constructor() { 12 | super() 13 | this.state = { 14 | search_type: '', 15 | message_text: '', 16 | to_email:'', 17 | subject: '', 18 | course_filter: 0, 19 | rescode: 0, 20 | messages: [], 21 | showComponenthome : false 22 | 23 | }; 24 | 25 | this.onChangeText = this.onChangeText.bind(this) 26 | this.onChangeRadio = this.onChangeRadio.bind(this) 27 | this._onLinkClick = this._onLinkClick.bind(this); 28 | } 29 | 30 | _onLinkClick(e) { 31 | 32 | console.log("clicked subject link") 33 | this.setState({ 34 | showComponenthome: false, 35 | // hideAllComponent:true 36 | }); 37 | 38 | console.log("state.showcomponentPpl1" + this.state.showComponentPpl) 39 | } 40 | 41 | onChangeText (e) { 42 | this.setState({ [e.target.name]: e.target.value }) 43 | } 44 | 45 | onChangeRadio (e) { 46 | this.setState({ search_type : e.target.value }) 47 | } 48 | 49 | componentDidMount () { 50 | 51 | // socket.on('message', msg => console.log("messages from socket: " + msg)) 52 | const token = localStorage.getItem('usertoken'); 53 | axios.get('/users/message_list', 54 | {headers:{'Content-Type': 'application/json','Authorization': `Bearer ${token}`}} 55 | ) 56 | .then((response) => { 57 | console.log("response subject messages" + JSON.stringify(response)) 58 | //update the state with the response data 59 | 60 | this.setState({ 61 | messages : response.data 62 | }); 63 | 64 | if(response.status===200){ 65 | this.setState({ 66 | showComponenthome : true 67 | }); 68 | } 69 | 70 | }) 71 | .catch(err => { 72 | console.log(err) 73 | }) 74 | } 75 | 76 | render () { 77 | let redirectVar = null; 78 | if(!cookie.load('cookie')){ 79 | redirectVar = 80 | } 81 | 82 | let details = []; 83 | 84 | if(this.state.showComponenthome) 85 | { 86 | let det = this.state.messages.map(msgs => { 87 | 88 | return( 89 | 90 | {msgs.fromemail} 91 | {msgs.toemail} 92 | {msgs.subject} 93 | 94 | ) 95 | 96 | }) 97 | 98 | details = 99 | 100 |
    101 |
    102 | {redirectVar} 103 |
    104 |
    105 |
    106 |
    107 | 108 |
    109 | New Message 110 |

    Message List

    111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | {det} 122 | 123 |
    From To Subject
    124 |
    125 |
    126 |
    127 |
    128 |
    129 |
    130 |
    131 | } 132 | 133 | return( 134 |
    135 | {redirectVar} 136 | {details} 137 |
    138 | ) 139 | } 140 | } 141 | 142 | export default Inbox -------------------------------------------------------------------------------- /frontend/src/components/SubmissionViewer.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PDF from 'react-pdf-js'; 3 | import axios from 'axios'; 4 | import {Link} from 'react-router-dom'; 5 | 6 | class SubmissionViewer extends Component { 7 | constructor(props) { 8 | super(props); 9 | this.state = { 10 | // assn_id:'', 11 | // user_email:'', 12 | assn_rec:{}, 13 | rescode:0 14 | } 15 | 16 | } 17 | 18 | componentWillMount(){ 19 | console.log("params " + JSON.stringify(this.props.match.params)) 20 | 21 | const { user_email,assn_id,course_id } = this.props.match.params 22 | /* 23 | this.setState({ 24 | assn_id : assn_id,user_email: user_email 25 | }); 26 | console.log("assn id: " + JSON.stringify(this.state.ass_id)) 27 | console.log("user email: " + JSON.stringify(this.state.user_email)) 28 | */ 29 | 30 | console.log("assn id: " + assn_id) 31 | console.log("user email: " + user_email) 32 | axios.get('http://localhost:3001/users/path' 33 | ,{ 34 | params:{assn_id: assn_id,user_email:user_email}} 35 | ) 36 | .then((response) => { 37 | console.log("response: " + JSON.stringify(response.data)) 38 | let assnr = JSON.stringify(response.data) 39 | this.setState({ 40 | assn_rec : response.data 41 | 42 | }); 43 | console.log("first " + JSON.stringify(assnr)) 44 | console.log("first2 " + JSON.stringify(this.state.assn_rec)) 45 | console.log("path " + JSON.stringify(this.state.assn_rec.user_file)) 46 | console.log("path1" + this.state.assn_rec.user_file) 47 | console.log("c " + JSON.stringify(this.state.assn_rec.course_id)) 48 | console.log("c1 " + this.state.assn_rec.course_id) 49 | //update the state with the response data 50 | 51 | 52 | 53 | if(response){ 54 | this.setState({ 55 | rescode: 200 56 | 57 | }); 58 | } 59 | 60 | }) 61 | .catch(err => { 62 | console.log(err) 63 | }) 64 | } 65 | 66 | onDocumentComplete = (pages) => { 67 | this.setState({ page: 1, pages }); 68 | } 69 | 70 | handlePrevious = () => { 71 | this.setState({ page: this.state.page - 1 }); 72 | } 73 | 74 | handleNext = () => { 75 | this.setState({ page: this.state.page + 1 }); 76 | } 77 | 78 | renderPagination = (page, pages) => { 79 | let previousButton =
  • Previous
  • ; 80 | if (page === 1) { 81 | previousButton =
  • Previous
  • ; 82 | } 83 | let nextButton =
  • Next
  • ; 84 | if (page === pages) { 85 | nextButton =
  • Next
  • ; 86 | } 87 | return ( 88 | 94 | ); 95 | } 96 | 97 | render() { 98 | /* 99 | let f1 = this.state.assn_rec.map(assn => { return assn.user_file }) 100 | let c1 = this.state.assn_rec.map(assn => { return assn.course_id }) 101 | */ 102 | console.log("this.state.rescode: " + this.state.rescode) 103 | let pagination = null; 104 | if (this.state.pages) { 105 | pagination = this.renderPagination(this.state.page, this.state.pages); 106 | } 107 | // console.log("filename1 " +this.state.assn_rec.user_file + " " + f1 + " " + c1) 108 | console.log("filename2 " + JSON.stringify(this.state.assn_rec.user_file)) 109 | /* var file = '' 110 | file = 'http://localhost:3001/'+`${this.state.assn_rec.user_file}` 111 | console.log("filename a " + file) 112 | let newfile ='' 113 | newfile = file 114 | console.log("filename b " + newfile) 115 | */ 116 | let render1 = '' 117 | if(typeof(this.state.assn_rec.user_file)==="undefined"){ 118 | 119 | console.log("undefined") 120 | } 121 | else 122 | render1=
    123 | 124 | 129 | {pagination} 130 |
    131 | 132 | return ( 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 | {render1} 140 |
    141 |
    142 |
    143 |
    144 |
    145 | 146 |
    147 | ) 148 | } 149 | } 150 | 151 | export default SubmissionViewer; -------------------------------------------------------------------------------- /frontend/src/components/Signup.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Field, reduxForm } from "redux-form"; 3 | import { connect } from "react-redux"; 4 | import { signUp } from "../actions/userActions"; 5 | import PropTypes from 'prop-types'; 6 | 7 | class Signup extends Component { 8 | 9 | componentWillMount(){ 10 | this.setState({ 11 | rcode : 0 12 | }) 13 | } 14 | 15 | 16 | renderField(field) { 17 | const { meta: { touched, error } } = field; 18 | const className = `form-group ${touched && error ? "has-danger" : ""}`; 19 | 20 | return ( 21 |
    22 | 23 | 24 |
    25 | {touched ? error : ""} 26 |
    27 |
    28 | ); 29 | } 30 | renderField1(field) { 31 | const { meta: { touched, error } } = field; 32 | const className = `form-group ${touched && error ? "has-danger" : ""}`; 33 | 34 | return ( 35 |
    36 | 37 | 38 |
    39 | {touched ? error : ""} 40 |
    41 |
    42 | ); 43 | } 44 | 45 | onSubmit(values) { 46 | console.log("values: " + values); 47 | this.props.signUp(values, () => { 48 | console.log("i am here before push"); 49 | console.log("rescode onsumbit: " + JSON.stringify(this.props.rescode)) 50 | let stat_code = this.props.rescode 51 | let s_code = Object.keys(stat_code).map(function(key){ return stat_code[key] }) 52 | if(s_code==201) { 53 | this.props.history.push("/signin"); 54 | } 55 | else if(s_code==202){ 56 | console.log("Response code 202!"); 57 | this.setState({ 58 | rcode : 202 59 | })} 60 | else if(s_code==500){ 61 | this.setState({ 62 | rcode : 204 63 | }) 64 | } 65 | 66 | // if(Object.keys(this.props.rescode).map(function(key){ return this.props.rescode[key] })=='201') 67 | // this.props.history.push("/signin"); 68 | }); 69 | } 70 | 71 | 72 | 73 | render () { 74 | const { handleSubmit } = this.props; 75 | 76 | console.log("rescode: " + JSON.stringify(this.props.rescode)) 77 | 78 | let det = '' 79 | if(this.state.rcode==202) 80 | det=
    User already registered!
    81 | else if(this.state.rcode==500) 82 | det=
    Error!
    83 | 84 | 85 | return ( 86 |
    87 |
    88 |
    89 |
    90 |
    91 | 92 |
    93 |

    Sign Up

    94 | {det} 95 | 100 | 105 | 106 | 112 | 117 | 118 | 119 | 120 | 121 | 122 | 123 |
    124 |
    125 |
    126 |
    127 |
    128 | ) 129 | } 130 | } 131 | function validate(values) { 132 | 133 | const errors = {}; 134 | 135 | // Validate the inputs from 'values' 136 | if (!values.user_name) { 137 | errors.user_name = "Enter your name"; 138 | } 139 | if (!values.user_email) { 140 | errors.user_email = "Enter your email address"; 141 | } 142 | if (!values.user_password) { 143 | errors.user_password = "Enter password"; 144 | } 145 | if (!values.user_type) { 146 | errors.user_type = "Enter user type"; 147 | } 148 | 149 | // If errors is empty, the form is fine to submit 150 | // If errors has *any* properties, redux form assumes form is invalid 151 | return errors; 152 | } 153 | 154 | 155 | const mapStateToProps = state => ( 156 | { 157 | rescode: state.signup_status 158 | }); 159 | 160 | 161 | export default reduxForm({ 162 | validate, 163 | form: "SignupForm" 164 | })(connect(mapStateToProps, { signUp })(Signup)); 165 | 166 | -------------------------------------------------------------------------------- /frontend/src/components/GenCode.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | //import { genCode } from './myfunctions'; 3 | import {Redirect} from 'react-router'; 4 | import axios from 'axios'; 5 | import cookie from 'react-cookies'; 6 | 7 | class GenCode extends Component { 8 | constructor() { 9 | super() 10 | this.state = { 11 | courseDetails: [], 12 | course_wl_cap: '', 13 | arr:[] 14 | // enrollStatus: false 15 | }; 16 | 17 | this.onChangeText = this.onChangeText.bind(this) 18 | this.onViewDetails = this.onViewDetails.bind(this) 19 | this.onGenCode = this.onGenCode.bind(this) 20 | } 21 | onChangeText (e) { 22 | this.setState({ [e.target.name]: e.target.value }) 23 | } 24 | onViewDetails (e) { 25 | e.preventDefault() 26 | 27 | axios.get('/courseget',{ 28 | params:{course_id: this.state.course_id} 29 | }) 30 | .then((response) => { 31 | //update the state with the response data 32 | 33 | this.setState({ 34 | courseDetails : this.state.courseDetails.concat(response.data) 35 | 36 | }); 37 | 38 | }) 39 | .catch(err => { 40 | console.log(err) 41 | }) 42 | 43 | 44 | } 45 | 46 | onGenCode (e) { 47 | e.preventDefault() 48 | 49 | let arr = []; 50 | arr = Array.from({length: 6 }, () => Math.floor(Math.random() * 9)); 51 | while(arr.length < 8){ 52 | var r = Math.floor(Math.random()*100) + 1; 53 | if(arr.indexOf(r) === -1) arr.push(r); 54 | } 55 | console.log("arr new : " + arr); 56 | 57 | 58 | this.setState({ 59 | course_wl_cap : this.state.course_wl_cap, 60 | arr: this.state.arr 61 | 62 | }); 63 | console.log("cap : " + this.state.course_wl_cap) 64 | 65 | } 66 | 67 | 68 | render(){ 69 | 70 | let redirectVar = null; 71 | if(!cookie.load('cookie')){ 72 | redirectVar = 73 | } 74 | 75 | let details = []; 76 | details = this.state.courseDetails.map(course => { 77 | 78 | return( 79 | 80 | {course.course_id} 81 | {course.course_dep} 82 | 83 | {course.course_term} 84 | 85 | {course.course_cap} 86 | {course.course_wl_cap} 87 | 88 | {course.course_enrollment_count} 89 | {course.course_wl_count} 90 | 91 | 92 | ) 93 | 94 | }) 95 | 96 | 97 | return( 98 |
    99 |
    100 | {redirectVar} 101 |
    102 |
    103 |
    104 |
    105 |
    106 | 107 |
    108 |

    Generate Permission Code

    109 |

    Enter Course ID

    110 |
    111 | 112 |
    113 | 115 |
    116 | 117 | 118 |
    119 |
    120 |
    121 |
    122 |
    123 |
    124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | {details} 138 | 139 | {this.state.arr} 140 |
    IDDeptTermMax CapacityWL CapEnrolledWL
    141 |
    142 |
    143 |
    144 |
    145 |
    146 | ) 147 | } 148 | } 149 | 150 | export default GenCode -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | //const app = express.Router() 4 | const mysql = require('mysql'); 5 | var bodyParser = require('body-parser'); 6 | var sessions = require('express-session'); 7 | var cookieParser = require('cookie-parser'); 8 | var cors = require('cors'); 9 | const multer = require('multer') 10 | var multiparty = require('multiparty'); 11 | var fs = require('fs'); 12 | //var multer = require('multer') 13 | var multipart = require('connect-multiparty'); 14 | var multipartMiddleware = multipart(); 15 | var FormData = require('form-data'); 16 | var Sequelize = require('sequelize'); 17 | var mongoose = require("mongoose"); 18 | const passport = require('passport'); 19 | var User = require("./model/user"); 20 | var kafka = require('./kafka/client'); 21 | 22 | // Passport Config 23 | var passportJWT = require("passport-jwt"); 24 | 25 | var ExtractJwt = passportJWT.ExtractJwt; 26 | var JwtStrategy = passportJWT.Strategy; 27 | 28 | 29 | //mongo connection 30 | mongoose.connect( 31 | "mongodb+srv://canvas_user:2407Rakhee%21@cluster0-jjkgt.mongodb.net/canvasdb?poolSize=10?retryWrites=true", 32 | // "mongodb+srv://canvas_user:2407Rakhee%21@cluster0-jjkgt.mongodb.net/canvasdb?retryWrites=true", 33 | { 34 | useNewUrlParser: true, 35 | // autoReconnect: true, 36 | // reconnectTries: Number.MAX_VALUE, 37 | // keepAlive: true, 38 | //connectTimeoutMS: 6000, 39 | // socketTimeoutMS: 6000 40 | } 41 | ); 42 | mongoose.connection.on("connected", () => { 43 | console.log("Connected to database!"); 44 | }); 45 | mongoose.connection.on("error", err => { 46 | console.log(err); 47 | }); 48 | 49 | var jwtOptions = {} 50 | jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('Bearer'); 51 | jwtOptions.secretOrKey = 'studentuserkey'; 52 | 53 | var strategy = new JwtStrategy(jwtOptions, function(jwt_payload, next) { 54 | console.log('payload received', jwt_payload); 55 | // usually this would be a database call: 56 | return User.findOne({ 57 | user_email: jwt_payload.user_email, 58 | user_type: jwt_payload.user_type 59 | }) 60 | .then(user => { 61 | if (user) { 62 | return next(null, user); 63 | } else { 64 | return next(null, false); 65 | } 66 | }); 67 | }) 68 | 69 | // var user = users[_.findIndex(users, {id: jwt_payload.id})]; 70 | 71 | 72 | passport.use(strategy); 73 | 74 | app.use(require('express-session')({ 75 | secret: 'keyboardsecret', 76 | resave: false, 77 | saveUninitialized: false 78 | })); 79 | app.use(passport.initialize()); 80 | //app.use(passport.session()); 81 | 82 | const Op = Sequelize.Op; 83 | //use cors to allow cross origin resource sharing 84 | app.use(cors({ origin: 'http://localhost:3000', credentials: true })); 85 | //app.use(cors()); 86 | process.env.SECRET_KEY = 'secret' 87 | 88 | //use express session to maintain session data 89 | // 90 | app.use(cookieParser()); 91 | //app.use('/', routes); 92 | app.use(express.static('public')); 93 | app.use(sessions({ 94 | secret : 'cmpe273_secret', 95 | resave : true, 96 | saveUninitialized : true, 97 | duration : 60 * 60 * 1000,    // duration of Session : 30 minutes : 1800 seconds 98 | activeDuration : 5 * 60 * 1000 99 | })); 100 | 101 | 102 | app.use(bodyParser.urlencoded({ extended: true })) 103 | app.use(bodyParser.json()); 104 | 105 | app.use(function(req, res, next) { 106 | res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); 107 | res.header('Access-Control-Allow-Credentials', 'true'); 108 | res.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,POST,PUT,DELETE'); 109 | res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers'); 110 | // res.Header('Cache-Control', 'no-cache'); 111 | // res.Header('content-type', 'text/html'); 112 | next(); 113 | }); 114 | 115 | app.use('/profile_uploads',express.static('profile_uploads')); 116 | 117 | const file_storage = multer.diskStorage({ 118 | destination: function (req, file, cb) { 119 | console.log("in cb file destination : ",file.originalname); 120 | cb(null, './profile_uploads/') 121 | }, 122 | filename: function (req, file, cb) { 123 | console.log("in cb file Body : ",file.originalname); 124 | cb(null, new Date().toISOString() + file.originalname) 125 | } 126 | }) 127 | 128 | const fileFilter = (req,file,cb) => { 129 | //store a file 130 | if(file.mimetype==='image/jpeg' || file.mimetype==='image/png') 131 | cb(null,true) 132 | else 133 | //reject a file 134 | cb(null,false) 135 | } 136 | 137 | const upload = multer({ storage: file_storage ,fileFilter:fileFilter}); 138 | //var upload = multer({ storage: file_storage ,fileFilter:fileFilter}).single('common_name'); 139 | 140 | 141 | 142 | 143 | app.use('/users', require('./routes/users.js')) 144 | app.use('/course', require('./routes/course.js')) 145 | 146 | //module.exports = app 147 | 148 | 149 | 150 | const port = process.env.PORT || 3001; 151 | app.listen(port, () => { 152 | console.log(`server started on port ${port}`); 153 | }); 154 | -------------------------------------------------------------------------------- /frontend/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /frontend/src/components/Inbox/NewMessage.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Field, reduxForm } from "redux-form"; 3 | import { connect } from "react-redux"; 4 | import { newMsg } from "../../actions/msgActions"; 5 | import PropTypes from 'prop-types'; 6 | 7 | class NewMessage extends Component { 8 | 9 | componentWillMount(){ 10 | this.setState({ 11 | rcode : 0 12 | }) 13 | } 14 | 15 | 16 | renderField(field) { 17 | const { meta: { touched, error } } = field; 18 | const className = `form-group ${touched && error ? "has-danger" : ""}`; 19 | 20 | return ( 21 |
    22 | 23 | 24 |
    25 | {touched ? error : ""} 26 |
    27 |
    28 | ); 29 | } 30 | renderField1(field) { 31 | const { meta: { touched, error } } = field; 32 | const className = `form-group ${touched && error ? "has-danger" : ""}`; 33 | 34 | return ( 35 |
    36 | 37 |