├── .gitignore ├── README.md ├── calc ├── .babelrc ├── .eslintrc ├── bundle.js ├── calcapp.js ├── entry.js ├── index.html ├── package.json ├── style.css └── webpack.config.js ├── ee_forum ├── .babelrc ├── .eslintignore ├── .eslintrc.json ├── data │ ├── Posts.json │ └── Users.json ├── devServer.js ├── index.html ├── package.json ├── public │ └── .keep ├── server │ ├── api.js │ ├── app.js │ └── run.js ├── src │ ├── components │ │ ├── Header.js │ │ ├── LoginPage.js │ │ ├── NewPostPage.js │ │ ├── NotFoundPage.js │ │ ├── PostListPage.js │ │ ├── UserInfoPage.js │ │ └── UserStat.js │ ├── index.js │ ├── routes.js │ └── styles │ │ ├── Header.css │ │ ├── LoginPage.css │ │ ├── NewPostPage.css │ │ ├── PostListPage.css │ │ ├── UserInfoPage.css │ │ └── UserStat.css ├── webpack.config.dev.js └── webpack.config.prod.js ├── hw1 ├── index.html ├── styles.css └── todo.js ├── hw11 └── script.sql ├── hw2 ├── counter.js ├── curry_sum.js ├── getType.js └── index.html ├── hw3 ├── .babelrc ├── .eslintrc ├── bundle.js ├── entry.js ├── index.html ├── package.json ├── style.css ├── todoapp.js └── webpack.config.js ├── hw4 ├── .babelrc ├── .eslintrc ├── dist │ └── bundle.js ├── index.html ├── package.json ├── src │ ├── component │ │ ├── ChatApp.js │ │ ├── MessageItem.js │ │ └── ThreadItem.js │ ├── entry.js │ └── style.css └── webpack.config.js ├── hw5 ├── package.json ├── public │ └── example.jpg ├── server.js └── views │ ├── error.nunjucks │ ├── index.html │ └── index.nunjucks ├── hw6 ├── .babelrc ├── .eslintrc ├── dist │ └── bundle.js ├── image │ ├── chen.jpg │ ├── chiang1.jpg │ ├── chiang2.jpg │ ├── fun.jpg │ ├── lee.jpg │ ├── ma.png │ └── tsai.png ├── index.html ├── package.json ├── src │ ├── component │ │ ├── ChatApp.js │ │ ├── MessageItem.js │ │ └── ThreadItem.js │ ├── entry.js │ └── style.css └── webpack.config.js ├── hw7 ├── .babelrc ├── .eslintrc ├── dist │ └── bundle.js ├── index.html ├── package.json ├── server.js ├── src │ ├── component │ │ ├── ChatApp.js │ │ ├── MessageItem.js │ │ ├── ThreadItem.js │ │ └── UserData.js │ ├── entry.js │ ├── pages │ │ ├── NotFound.js │ │ ├── Root.js │ │ └── User.js │ └── style.css ├── webpack.config.dev.js └── webpack.config.js ├── hw8 ├── .babelrc ├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── README.md ├── devServer.js ├── index.html ├── package.json ├── public │ ├── .keep │ ├── bundle.js │ ├── bundle.js.map │ ├── style.css │ └── style.css.map ├── server │ ├── api.js │ ├── app.js │ └── run.js ├── src │ ├── components │ │ ├── NotFoundPage.js │ │ ├── SingleUserPage.css │ │ ├── SingleUserPage.js │ │ ├── UsersPage.css │ │ └── UsersPage.js │ ├── index.js │ └── routes.js ├── webpack.config.dev.js └── webpack.config.prod.js ├── index.html ├── index ├── images │ ├── body-bg.png │ ├── highlight-bg.jpg │ ├── hr.png │ ├── octocat-icon.png │ ├── tar-gz-icon.png │ └── zip-icon.png ├── javascripts │ └── main.js └── stylesheets │ ├── github-dark.css │ ├── print.css │ ├── selfdefine.css │ └── stylesheet.css └── params.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directories 27 | node_modules 28 | jspm_packages 29 | 30 | # Optional npm cache directory 31 | .npm 32 | 33 | # Optional REPL history 34 | .node_repl_history 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Web Programming Project 2 | 3 | A central repo for all assignments. -------------------------------------------------------------------------------- /calc/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react", "es2015", "stage-0"] 3 | } -------------------------------------------------------------------------------- /calc/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | } -------------------------------------------------------------------------------- /calc/calcapp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | class CalcApp extends React.Component { 4 | constructor(props) { 5 | super(props); 6 | this.state = { 7 | num: "0", 8 | tempnum: 0, 9 | mode: 0, 10 | valid: true, 11 | }; 12 | this.resetState = this.resetState.bind(this); 13 | this.genAppend = this.genAppend.bind(this); 14 | this.genMode = this.genMode.bind(this); 15 | this.calculate = this.calculate.bind(this); 16 | this.invert = this.invert.bind(this); 17 | this.percent = this.percent.bind(this); 18 | } 19 | 20 | updateState() { 21 | this.setState({ 22 | num: this.state.num, 23 | tempnum: this.state.tempnum, 24 | mode: this.state.mode, 25 | valid: this.state.valid, 26 | }) 27 | } 28 | 29 | resetState() { 30 | this.state.num = "0"; 31 | this.state.mode = 0; 32 | this.state.tempnum = 0; 33 | this.state.valid = true; 34 | this.updateState(); 35 | } 36 | 37 | showNotImplemented() { 38 | console.warn('This function is not implemented yet.'); 39 | } 40 | 41 | genAppend(num) { 42 | function append() { 43 | if(this.state.num === "0" || this.state.num === "-0") this.state.num = this.state.num.slice(0,-1); 44 | if(!this.state.valid) { 45 | this.state.num = ""; 46 | this.state.valid = true; 47 | } 48 | this.state.num += num; 49 | this.updateState(); 50 | } 51 | append = append.bind(this); 52 | return append; 53 | } 54 | 55 | genMode(key) { 56 | function mode() { 57 | this.calculate(); 58 | if(!key) { 59 | let str = this.state.num; 60 | this.resetState(); 61 | this.state.num = str; 62 | } 63 | else this.state.mode = key; 64 | this.updateState(); 65 | } 66 | mode = mode.bind(this); 67 | return mode; 68 | } 69 | 70 | calculate() { 71 | if(!this.state.valid) return; 72 | if(this.state.mode === 0) { 73 | this.state.tempnum = +this.state.num; 74 | } 75 | else if(this.state.mode === 1) { 76 | this.state.tempnum += +this.state.num; 77 | } 78 | else if(this.state.mode === 2) { 79 | this.state.tempnum -= +this.state.num; 80 | } 81 | else if(this.state.mode === 3) { 82 | this.state.tempnum *= +this.state.num; 83 | } 84 | else if(this.state.mode === 4) { 85 | this.state.tempnum /= +this.state.num; 86 | } 87 | else if(this.state.mode === 5) return; 88 | 89 | this.state.num = this.state.tempnum.toString(); 90 | 91 | this.state.valid = false; 92 | } 93 | 94 | invert() { 95 | if(!this.state.valid) this.state.num = "0"; 96 | if(this.state.num[0] !== '-') this.state.num = "-" + this.state.num; 97 | else this.state.num = this.state.num.substr(1); 98 | this.updateState(); 99 | } 100 | 101 | percent() { 102 | if(!this.state.valid) this.state.num = "0"; 103 | this.state.num = +this.state.num / 100; 104 | this.updateState(); 105 | } 106 | 107 | render() { 108 | return ( 109 |
110 |
111 |
112 |
{this.state.num}
113 |
114 |
115 | AC 116 | +/- 117 | % 118 | ÷ 119 |
120 |
121 | 7 122 | 8 123 | 9 124 | × 125 |
126 |
127 | 4 128 | 5 129 | 6 130 | - 131 |
132 |
133 | 1 134 | 2 135 | 3 136 | + 137 |
138 |
139 | 0 140 | . 141 | = 142 |
143 |
144 |
145 | ); 146 | } 147 | } 148 | 149 | 150 | class CalcButton extends React.Component { 151 | render() { 152 | const { className, children, onClick } = this.props; 153 | return ( 154 |
158 | {children} 159 |
160 | ); 161 | } 162 | } 163 | 164 | CalcButton.propTypes = { 165 | className: React.PropTypes.string, 166 | children: React.PropTypes.string.isRequired, 167 | onClick: React.PropTypes.func 168 | }; 169 | 170 | CalcButton.defaultProps = { 171 | onClick: () => {} 172 | }; 173 | 174 | 175 | export default CalcApp; -------------------------------------------------------------------------------- /calc/entry.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; 3 | import CalcApp from './calcapp' 4 | import './style.css' 5 | 6 | render(, document.getElementById('root')); -------------------------------------------------------------------------------- /calc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CalcApp 6 | 7 | 8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /calc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "calculator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "topjohnwu", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-loader": "^6.2.4", 13 | "babel-preset-es2015": "^6.6.0", 14 | "babel-preset-react": "^6.5.0", 15 | "babel-preset-stage-0": "^6.5.0", 16 | "css-loader": "^0.23.1", 17 | "style-loader": "^0.13.1", 18 | "react": "^15.0.1", 19 | "react-dom": "^15.0.1" 20 | }, 21 | "dependencies": { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /calc/style.css: -------------------------------------------------------------------------------- 1 | li { 2 | list-style: none; 3 | } 4 | 5 | a { 6 | text-decoration: none; 7 | } 8 | 9 | a:hover { 10 | text-decoration: none; 11 | cursor: pointer; 12 | } 13 | 14 | /* layout */ 15 | .calc-container { 16 | width: 249px; 17 | height: 444px; 18 | margin: auto; 19 | background-color: black; 20 | } 21 | 22 | .calc-output { 23 | height: 139px; 24 | position: relative; 25 | } 26 | 27 | .calc-display { 28 | position: absolute; 29 | bottom: 5px; 30 | right: 15px; 31 | font-size: 50px; 32 | font-family: 'Lato', sans-serif; 33 | color: white; 34 | } 35 | 36 | .calc-row { 37 | height: 61px; 38 | } 39 | 40 | .calc-btn { 41 | cursor: pointer; 42 | display: inline-block; 43 | text-align: center; 44 | vertical-align: top; 45 | width: 60px; 46 | height: 60px; 47 | line-height: 60px; 48 | border: 1px solid #a08c88; 49 | background-color: #c8c9cb; 50 | } 51 | 52 | .calc-btn { 53 | cursor: pointer; 54 | display: inline-block; 55 | text-align: center; 56 | vertical-align: top; 57 | width: 60px; 58 | height: 60px; 59 | line-height: 60px; 60 | border: 1px solid #a08c88; 61 | background-color: #c8c9cb; 62 | } 63 | 64 | .calc-number { 65 | background-color: #d2d3d5; 66 | } 67 | 68 | .calc-number-0 { 69 | width: 122px; 70 | background-color: #d2d3d5; 71 | } 72 | 73 | .calc-operator { 74 | color: white; 75 | background-color: #f58c00; 76 | } 77 | 78 | 79 | 80 | /* clearfix 81 | * http://stackoverflow.com/questions/211383/which-method-of-clearfix-is-best 82 | */ 83 | .clearfix:before, 84 | .clearfix:after { 85 | content:""; 86 | display:table; 87 | } 88 | .clearfix:after { 89 | clear:both; 90 | } 91 | .clearfix { 92 | zoom:1; /* For IE 6/7 (trigger hasLayout) */ 93 | } -------------------------------------------------------------------------------- /calc/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devtool: 'cheap-module-eval-source-map', 3 | entry: './entry', // 進入點 4 | output: { 5 | filename: 'bundle.js', // 輸出的檔案名稱 6 | }, 7 | module: { 8 | loaders: [{ 9 | test: /\.js$/, // 針對 js 檔 10 | loaders: ['babel'], 11 | exclude: /node_modules/ // 不要處理 3rd party 的 code 12 | }, { 13 | test: /\.css$/, // 針對 css 檔 14 | loaders: ['style', 'css'], 15 | exclude: /node_modules/ // 不要處理 3rd party 的 code 16 | }] 17 | } 18 | }; -------------------------------------------------------------------------------- /ee_forum/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react", "es2015", "stage-0"], 3 | "env": { 4 | "development": { 5 | "presets": ["react-hmre"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ee_forum/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public/bundle.js 3 | -------------------------------------------------------------------------------- /ee_forum/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extend": "airbnb", 4 | "rules": { 5 | "react/prefer-stateless-function": 0 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /ee_forum/data/Posts.json: -------------------------------------------------------------------------------- 1 | [{"id":0,"op":1,"time":1463640041767,"title":"LOL","content":":)","up":0,"down":0},{"id":1,"op":2,"time":1463642240731,"title":"Good :)","content":"Ahhhhh....\nNice ^ ^","up":0,"down":0}] -------------------------------------------------------------------------------- /ee_forum/data/Users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "id": 0 }, 3 | { "id": 1, "name": "John", "password": "john", "pic": "http://thisismykea2.s3.amazonaws.com/sites/default/files/designs/6995/mr-happy-1310118986.png"}, 4 | { "id": 2, "name": "Amy", "password": "amy", "pic": "http://i.imgur.com/tSfIYtw.png" } 5 | ] -------------------------------------------------------------------------------- /ee_forum/devServer.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console: 0 */ 2 | const path = require('path'); 3 | const express = require('express'); 4 | const webpack = require('webpack'); 5 | const proxy = require('proxy-middleware'); 6 | const config = require('./webpack.config.dev'); 7 | require('./server/run'); 8 | 9 | const API_PORT = 8080; 10 | const DEV_PORT = 3000; 11 | 12 | const app = express(); 13 | const compiler = webpack(config); 14 | 15 | app.use(require('webpack-dev-middleware')(compiler, { 16 | noInfo: true, 17 | publicPath: config.output.publicPath, 18 | })); 19 | 20 | app.use(require('webpack-hot-middleware')(compiler)); 21 | 22 | app.use('/public', express.static('public')); 23 | app.use('/api', proxy(`http://localhost:${API_PORT}/api`)); 24 | 25 | app.get('*', (req, res) => { 26 | res.sendFile(path.join(__dirname, 'index.html')); 27 | }); 28 | 29 | app.listen(DEV_PORT, (err) => { 30 | if (err) { 31 | console.log(err); 32 | return; 33 | } 34 | 35 | console.log('Listening at http://localhost:3000'); 36 | }); 37 | -------------------------------------------------------------------------------- /ee_forum/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EE Forum 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ee_forum/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ee_forum", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "eslint .", 8 | "start": "node devServer", 9 | "build": "NODE_ENV=production webpack --config webpack.config.prod.js", 10 | "start:prod": "NODE_ENV=production node server/run.js", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "keywords": [], 14 | "author": "", 15 | "license": "ISC", 16 | "dependencies": { 17 | "babel-polyfill": "^6.8.0", 18 | "body-parser": "^1.15.1", 19 | "classnames": "^2.2.5", 20 | "express": "^4.13.4", 21 | "fs": "0.0.2", 22 | "isomorphic-fetch": "^2.2.1", 23 | "morgan": "^1.7.0", 24 | "react": "^15.0.2", 25 | "react-dom": "^15.0.2", 26 | "react-router": "^2.4.0" 27 | }, 28 | "devDependencies": { 29 | "babel-eslint": "^6.0.4", 30 | "babel-loader": "^6.2.4", 31 | "babel-preset-es2015": "^6.6.0", 32 | "babel-preset-react": "^6.5.0", 33 | "babel-preset-react-hmre": "^1.1.1", 34 | "babel-preset-stage-0": "^6.5.0", 35 | "css-loader": "^0.23.1", 36 | "eslint": "^2.9.0", 37 | "eslint-config-airbnb": "^8.0.0", 38 | "eslint-plugin-import": "^1.6.1", 39 | "eslint-plugin-jsx-a11y": "^1.0.4", 40 | "eslint-plugin-react": "^5.0.1", 41 | "extract-text-webpack-plugin": "^1.0.1", 42 | "proxy-middleware": "^0.15.0", 43 | "style-loader": "^0.13.1", 44 | "webpack": "^1.13.0", 45 | "webpack-dev-middleware": "^1.6.1", 46 | "webpack-hot-middleware": "^2.10.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ee_forum/public/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/topjohnwu/Web-Programming-Project/822ff112c0c1e0ac143a986fffb5064344c8540f/ee_forum/public/.keep -------------------------------------------------------------------------------- /ee_forum/server/api.js: -------------------------------------------------------------------------------- 1 | const Router = require('express').Router; 2 | const router = new Router(); 3 | const bodyParser = require('body-parser'); 4 | const fs = require('fs'); 5 | const Users = require('../data/Users.json'); 6 | const Posts = require('../data/Posts.json'); 7 | 8 | router.use(bodyParser.urlencoded({ extended: false })); 9 | router.use(bodyParser.json()); 10 | 11 | 12 | router.post('/login/', function(req, res) { 13 | let user = 0; 14 | for(let i = 0; i < Users.length; ++i) { 15 | if(Users[i].name === req.body.username) { 16 | if(Users[i].password === req.body.password) { 17 | user = i; 18 | break; 19 | } 20 | } 21 | } 22 | if(user) 23 | res.json(Users[user]); 24 | else 25 | res.json(null); 26 | }); 27 | 28 | router.get('/users/', function(req, res) { 29 | res.json(Users); 30 | }); 31 | 32 | router.get('/users/:id', function(req, res, next) { 33 | if(req.params.id < 0 || req.params.id >= Users.length) { 34 | var err = new Error(); 35 | err.status = 404; 36 | err.message = 'This id doesn\'t exist' 37 | next(err); 38 | } 39 | else res.json(Users[req.params.id]); 40 | }); 41 | 42 | router.get('/posts/', function(req, res) { 43 | res.json(Posts); 44 | }); 45 | 46 | router.post('/posts/', function(req, res) { 47 | req.body.id = Posts.length; 48 | Posts.push(req.body); 49 | fs.writeFile('./data/Posts.json', JSON.stringify(Posts), (err) => { 50 | if (err) throw err; 51 | console.log('Posts saved to Post.json!'); 52 | }); 53 | res.json(true); 54 | }); 55 | 56 | router.use(function(err, req, res, next) { 57 | console.log("error occurs: " + err.message); 58 | res.status(err.status || 500); 59 | res.send(err); 60 | }); 61 | 62 | module.exports = router; 63 | -------------------------------------------------------------------------------- /ee_forum/server/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const logger = require('morgan'); 4 | const api = require('./api'); 5 | 6 | const app = express(); 7 | 8 | app.use(logger('dev')); 9 | app.use('/public', express.static(path.join(__dirname, '..', 'public'))); 10 | 11 | 12 | app.use('/api', api); 13 | app.use('*', (req, res) => { 14 | res.sendFile(path.join(__dirname, '..', 'index.html')); 15 | }); 16 | 17 | 18 | // error handlers 19 | 20 | // development error handler 21 | // will print stacktrace 22 | if (app.get('env') === 'development') { 23 | app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars 24 | res.status(err.status || 500); 25 | res.render('error', { 26 | message: err.message, 27 | error: err, 28 | }); 29 | }); 30 | } 31 | 32 | // production error handler 33 | // no stacktraces leaked to user 34 | app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars 35 | res.status(err.status || 500); 36 | res.render('error', { 37 | message: err.message, 38 | error: {}, 39 | }); 40 | }); 41 | 42 | 43 | module.exports = app; 44 | -------------------------------------------------------------------------------- /ee_forum/server/run.js: -------------------------------------------------------------------------------- 1 | /* eslint no-console: 0 */ 2 | const APIServer = require('./app'); 3 | 4 | const API_PORT = 8080; 5 | 6 | APIServer.listen(API_PORT, () => { 7 | console.log( 8 | `API Server is now running on http://localhost:${API_PORT}` 9 | ); 10 | }); 11 | -------------------------------------------------------------------------------- /ee_forum/src/components/Header.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react'; 2 | import 'babel-polyfill'; 3 | 4 | import NotFoundPage from './NotFoundPage'; 5 | import LoginPage from './LoginPage'; 6 | import PostListPage from './PostListPage'; 7 | import UserInfoPage from './UserInfoPage'; 8 | import UserStat from './UserStat'; 9 | 10 | import '../styles/Header.css' 11 | 12 | export default class Header extends Component { 13 | constructor(context) { 14 | super(context); 15 | this.state = { 16 | user: null, 17 | users: null, 18 | } 19 | this.users = null; 20 | } 21 | static contextTypes = { 22 | router: React.PropTypes.object.isRequired 23 | }; 24 | componentWillMount() { 25 | if(!this.state.user) 26 | if(this.props.location.pathname !== "/login") 27 | this.context.router.push('/login'); 28 | } 29 | componentDidMount() { 30 | fetch('/api/users') 31 | .then(res => { return res.json(); } ) 32 | .then(json => { this.setState( {users: json} ); }); 33 | } 34 | setUser(json) { 35 | this.setState( {user: json} ); 36 | } 37 | Child() { 38 | const children = React.Children.map(this.props.children, 39 | (child) => React.cloneElement(child, { 40 | user: this.state.user, 41 | users: this.state.users, 42 | setUser: this.setUser.bind(this), 43 | })); 44 | return children; 45 | } 46 | render() { 47 | if(!this.state.users) return null; 48 | return( 49 |
50 |
51 |
{this.context.router.push('/')} }>NTUEESA
52 |
53 |
{this.Child()}
54 |
55 | ) 56 | } 57 | } -------------------------------------------------------------------------------- /ee_forum/src/components/LoginPage.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import 'babel-polyfill'; 3 | import fetch from 'isomorphic-fetch'; 4 | import classNames from 'classnames' 5 | 6 | import '../styles/LoginPage.css' 7 | 8 | export default class LoginPage extends Component { 9 | constructor(props, context) { 10 | super(props, context); 11 | this.state = { 12 | valid: true, 13 | } 14 | } 15 | static contextTypes = { 16 | router: React.PropTypes.object.isRequired 17 | }; 18 | login(event) { 19 | fetch('/api/login', { 20 | method: 'post', 21 | headers: { 22 | 'Accept': 'application/json', 23 | 'Content-Type': 'application/json', 24 | }, 25 | body: JSON.stringify({ 26 | username: document.getElementById('username').value, 27 | password: document.getElementById('password').value, 28 | }), 29 | }) 30 | .then(res => { return res.json(); } ) 31 | .then(json => { 32 | if(json) { 33 | this.props.setUser(json); 34 | this.context.router.push('/'); 35 | } 36 | else 37 | this.setState( {valid: false} ); 38 | }) 39 | } 40 | 41 | render() { 42 | return( 43 |
44 |
EE Forum
45 |
46 |
Wrong password or account!
47 |
48 | 49 |
50 | 51 |
52 | 53 |
54 |
55 | ) 56 | } 57 | } -------------------------------------------------------------------------------- /ee_forum/src/components/NewPostPage.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import 'babel-polyfill'; 3 | import fetch from 'isomorphic-fetch'; 4 | 5 | import '../styles/NewPostPage.css' 6 | 7 | export default class NewPostPage extends Component { 8 | constructor(props, context) { 9 | super(props, context); 10 | } 11 | static contextTypes = { 12 | router: React.PropTypes.object.isRequired 13 | }; 14 | addPost() { 15 | fetch('/api/posts', { 16 | method: 'post', 17 | headers: { 18 | 'Accept': 'application/json', 19 | 'Content-Type': 'application/json', 20 | }, 21 | body: JSON.stringify( 22 | { id: null, op: this.props.user.id, time: (new Date()).getTime(), 23 | title: document.getElementById('post-title').value, 24 | content: document.getElementById('post-content').value, 25 | up: 0, down: 0,}), 26 | }) 27 | .then(() => this.context.router.push('/') ); 28 | 29 | } 30 | render() { 31 | return ( 32 |
33 | 34 |
35 | 36 |