General Assembly WDI NYC August, 2107
- Mitchel Severe
- Mili Neykkova
- Asher Shaheen
Code Share is a platform that provide Groups an ability to code together without being together in one place. The app has an option to work on coding challenges which include TESTS or to work/share individual code collabratively. Users can also save the writen code in a JS format for their reference. The app provides a CODE EDITOR sourced from another NPM PACKAGE CODEMIRROR. The app also provides a feature where USERS can find coding events based on the USER input language. USERS will also be able to create their own events. These events are viewable by all USERS. The app has a feature for AUTHS thus enabling the USERS to create a unique profile.
- USER should be able to create a USER NAME ( NO AUTHS )
- USER should be able to view the coding challenges & the events on the main page
- USER should be able to select a challenge followed by a render of code editor for that challenge in a specific ROOM
- USER should be able to SAVE the code by an option of DOWNLOAD
- USER should be abe to view who is in the ROOM and who is typing should show
- USER should be able to CREATE or SEARCH coding events based on the language they provided
- AUTHS - option to REGISTER and LOGIN
- CHAT window in the ROOMS
- Providing tests for the code challenges
We utilized React.js for the UI. Socket.io was utilized on both sides the front and back end in order to keep sync with the server and the user. All of our API calls are being inititated from the server side to protect the API Keys. Code writen by users is being sent to the server via POST request and is being executed in a sandbox ENV. We utilized the CRUD functionality by giving the users an option to create their own events that are viewable to all users.
- React.js
- Node.js
- Express
- Socket.io
- PSQL
- JSX
- BootStrap
- Passport / Sessions
- Socket.io (Enabling Realtime. Connected with the chat box and code editor so all users see real time updates on all connected sockets)
- Moment & Moment-Duration-Format (Parsing Dates & Times received from API Response)
- Codemirror (React Code Editor Component. Set to be used in JS Language only)
- VM (Sandbox For Code Evaluation. To execute user code in its own ENV without effecting our own App's EVN)
- Chai, Expect, Assert & Check-Error (User Code Testing & Error Handlings)
- File-Saver (Option to download the User code in JS format)
- Google (Provided Lat & Lng from User Input ZIP)
- Meetup (Provided Events on requested ZIP CODE)
Code Eval (Backend)
const vm = require('vm');
const assert = require('assert');
const expect = require('chai').expect;
const chai = require('chai');
const checkError = require('check-error');
// evaluation of code with challenges and testing
let codeEval = (req, res, next) => {
let result;
let code = req.body.code;
const sandbox = { assert: assert, expect: expect, checkError: checkError, chai: chai };
vm.createContext(sandbox);
try {
result = vm.runInContext(code, sandbox);
res.locals.ref = result;
} catch (e) {
result = checkError.getMessage(e);
res.locals.ref = result;
}
next();
}
Code Eval (Front End)
// evaluating the code from the editor and setting state of the result
handleExecuteCode = (code, test) => {
if(code + test) {
axios.post('/code', {
code: code + test,
}).then(res => {
let obj = res.data.data;
console.log('frontend received--->', obj)
if (obj.__flags) {
this.setState({ codeResult: 'Nice Work! Test Passed!', alert: 'success' })
} else {
this.setState({ codeResult: 'Error: ' + res.data.data, 'alert': 'danger' })
}
socket.emit('test check', this.state.codeResult);
}).catch(err => console.log(err));
}
}
Socket.io
FRONT END
componentWillMount() {
this.props.user ?
socket.emit('user join', this.props.user) :
console.log('Null user');
}
componentDidMount() {
socket.on('user join', this.handleUsers);
socket.on('message', this.handleRecievedMessage);
socket.on('code', this.handleCodeFromSockets);
socket.on('checked', this.codeResultCheck);
// socket.on('leave', this.handleLeaveUser);
}
handleUsers = (users) => {
this.setState({users: users});
}
handleCodeFromSockets = (code) => {
this.setState({code: code});
}
codeResultCheck = (result) => {
this.setState({codeResult: result});
}
handleUpdateCodeState = (text) => {
socket.emit('coding', text);
this.setState({code: text});
}
handleRecievedMessage = (message) => {
let messages = this.state.messages;
messages.push(message);
this.setState({messages: messages});
}
handleMessageSubmit = (message) => {
socket.emit('send message', message);
}
BACK END
io.on('connection', (socket) => {
console.log('A new connection', socket.id);
socket.on('send message', (message) => {
messages.push(message);
io.emit('message', {
user: message.user,
text: message.text,
});
});
socket.on('user join', (user) => {
if (users.indexOf(user) === -1) {
users.push(user);
console.log(users);
} else console.log('already exist');
io.emit('user join', users);
});
socket.on('coding', (code) => {
socket.broadcast.emit('code', code);
});
socket.on('test check', (result) => {
io.emit('checked', result);
});
});
Events | Type |
---|---|
ID | SERIAL PRIMARY KEY |
Title | VARCHAR(255) |
Desc | TEXT |
date | DATE |
time | TIME |
user_id | INTEGER REFERENCES users(id) |
Users | Type |
---|---|
ID | SERIAL PRIMARY KEY |
username | VARCHAR(255) UNIQUE NOT NULL |
password_digest | TEXT NOT NULL |
VARCHAR(255) UNIQUE NOT NULL | |
firstname | TEXT NOT NULL |
lastname | TEXT NOT NULL |
Front End
|_ client
|_ node_modules
|_ public
|_ src
|_ challenges (JS file containing an array of challenges)
|_ components
| |_ ApiEventList.jsx
| |_ ChallengesList.jsx
| |_ Chat.jsx
| |_ CodeEditor.jsx
| |_ EventAddForm.jsx
| |_ EventList.jsx
| |_ Footer.jsx
| |_ Home.jsx
| |_ Login.jsx
| |_ MainNav.jsx
| |_ NotLoggedNav.jsx
| |_ Register.jsx
| |_ SingleChallenge.jsx
|__ App.js
|__ App.css
|__ index.js
|__ index.css
Back End
|_ controllers
| |_ events-controller.js
| |_ users-controller.js
|
|_ db
| |_ migrations
| | |_ migration-082117.sql
| |_ config.js
|
|_ models
| |_ events.js
| |_ user.js
|
|_ routes
| |_ auth-routes.js
| |_ code-routes.js
| |_ event-routes.js
| |_ meetup-routes.js
| |_ user-routes.js
|
|_ services
| |_ auth
| | |_ auth-helpers.js
| | |_ local.js
| | |_ passport.js
| |
| |_ code
| | |_ code-helper.js
| |
| |_ meetup
| |_ meetup-helper
|
|_ app.js
- Yarn install from the MAIN PROJECT FOLDER & THE CLIENT FOLDER to install all dependencies
- Few Changes need to happen before you start servers: * In Client/src/components two files need an update. (SingleChallenge.jsx & CodeEditor.jsx) Please make the following change to line # 26 in both files.
```
const socket = io.connect();
// change to
const socket = io.connect('http://localhost:3001');
// save and run servers after this change
```
- Getting the tests to work in the SANDBOX ENV especially having 4 different NPM Packages work together
- Sockets.io to update and reflect the changes once a new USER joins the room
- Redirecting to HOME page after a USER logs in
- When a new EVENT is created by a USER, the change should reflect without refreshing the page
- Integrating Mocha Tests for the challenges
List of Bugs / Future Improvements
- Have an idea or a solution to the current bugs. Open up a PR and share.