From a0ddcff31346670f8ed1761572a828ea46d50965 Mon Sep 17 00:00:00 2001 From: hongchiong Date: Fri, 11 Jan 2019 18:21:27 +0800 Subject: [PATCH 1/5] show all tweets --- index.js | 61 +++++++++++++++++++++++---------------- seed.sql | 20 +++++++++++++ tables.sql | 26 +++++++++++++++++ views/home.jsx | 30 +++++++++++++++++++ views/layouts/default.jsx | 39 +++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 25 deletions(-) create mode 100644 seed.sql create mode 100644 tables.sql create mode 100644 views/home.jsx create mode 100644 views/layouts/default.jsx diff --git a/index.js b/index.js index 4d5d595..c03da7f 100644 --- a/index.js +++ b/index.js @@ -1,91 +1,102 @@ const express = require('express'); const methodOverride = require('method-override'); const cookieParser = require('cookie-parser'); - const pg = require('pg'); - +const sha256 = require('js-sha256'); /** * =================================== * Configurations and set up * =================================== */ - const configs = { - user: 'akira', + user: 'postgres', host: '127.0.0.1', - database: 'testdb', + database: 'tweedr', port: 5432, + password: 'pg' }; - const pool = new pg.Pool(configs); - pool.on('error', function (err) { console.log('idle client error', err.message, err.stack); }); - // Init express app const app = express(); - // Set up middleware app.use(methodOverride('_method')); app.use(cookieParser()); app.use(express.urlencoded({ extended: true })); - // Set react-views to be the default view engine const reactEngine = require('express-react-views').createEngine(); app.set('views', __dirname + '/views'); app.set('view engine', 'jsx'); app.engine('jsx', reactEngine); - /** * =================================== * Routes * =================================== */ +//============================================================== + + -// Root GET request (it doesn't belong in any controller file) -app.get('/', (request, response) => { - response.send('Welcome To Tweedr.'); +// SHOW ALL TWEETS +//============================================================== +app.get('/', (req, res) => { + let query = "SELECT * FROM tweets;"; + + pool.query(query, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + let resultArr = [result.rows]; + res.render('home', resultArr); + // res.send(resultArr); + } + }); }); -app.get('/users/new', (request, response) => { - response.render('user/newuser'); + +//============================================================== +app.get('/users/new', (req, res) => { + res.render('user/newuser'); }); -app.post('/users', (request, response) => { +app.post('/users', (req, res) => { const queryString = 'INSERT INTO users (name, password) VALUES ($1, $2)'; const values = [ - request.body.name, - request.body.password + req.body.name, + req.body.password ]; // execute query pool.query(queryString, values, (error, queryResult) => { - //response.redirect('/'); - response.send('user created'); + //res.redirect('/'); + res.send('user created'); }); }); + + + + +//============================================================== /** * =================================== * Listen to requests on port 3000 * =================================== */ - const server = app.listen(3000, () => console.log('~~~ Tuning in to the waves of port 3000 ~~~')); - let onClose = function(){ - server.close(() => { console.log('Process terminated') pool.end( () => console.log('Shut down db connection pool')); }) }; - process.on('SIGTERM', onClose); process.on('SIGINT', onClose); diff --git a/seed.sql b/seed.sql new file mode 100644 index 0000000..9ed514d --- /dev/null +++ b/seed.sql @@ -0,0 +1,20 @@ +INSERT INTO users (name, password) VALUES ('Jason', 'Nosaj'); +INSERT INTO users (name, password) VALUES ('Jolly', 'Ylloj'); +INSERT INTO users (name, password) VALUES ('Josh', 'Hsoj'); +INSERT INTO users (name, password) VALUES ('Jobs', 'Sboj'); + +INSERT INTO tweets (content, author_id) VALUES ('Hungry Sia', 2); +INSERT INTO tweets (content, author_id) VALUES ('I wanna go home', 1); +INSERT INTO tweets (content, author_id) VALUES ('Josh Rocks', 3); +INSERT INTO tweets (content, author_id) VALUES ('King of the world', 3); +INSERT INTO tweets (content, author_id) VALUES ('Bring me back to life', 4); +INSERT INTO tweets (content, author_id) VALUES ('Cook is killing Apple', 4); + +INSERT INTO users_followers (user_id, follower_id) VALUES (4, 3); +INSERT INTO users_followers (user_id, follower_id) VALUES (4, 2); +INSERT INTO users_followers (user_id, follower_id) VALUES (4, 1); +INSERT INTO users_followers (user_id, follower_id) VALUES (3, 4); +INSERT INTO users_followers (user_id, follower_id) VALUES (2, 3); +INSERT INTO users_followers (user_id, follower_id) VALUES (2, 1); +INSERT INTO users_followers (user_id, follower_id) VALUES (1, 2); +INSERT INTO users_followers (user_id, follower_id) VALUES (1, 4); \ No newline at end of file diff --git a/tables.sql b/tables.sql new file mode 100644 index 0000000..17555b5 --- /dev/null +++ b/tables.sql @@ -0,0 +1,26 @@ +CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + name TEXT, + password TEXT +); + +CREATE TABLE IF NOT EXISTS tweets ( + id SERIAL PRIMARY KEY, + content TEXT, + author_id INTEGER, + tweeted_on TIMESTAMPTZ DEFAULT now() +); + +CREATE TABLE IF NOT EXISTS users_followers ( + id SERIAL PRIMARY KEY, + user_id INTEGER, + follower_id INTEGER +); + +-- psql -d tweedr -U postgres -f tables.sql + + +-- Queries + +-- Find followers of a certain user +-- SELECT * FROM users INNER JOIN users_followers ON (users_followers.follower_id = users.id) WHERE users_followers.user_id = 3; diff --git a/views/home.jsx b/views/home.jsx new file mode 100644 index 0000000..b01b1d8 --- /dev/null +++ b/views/home.jsx @@ -0,0 +1,30 @@ +var React = require("react"); +var DefaultLayout = require('./layouts/default'); + +class Home extends React.Component { + render() { + + const tweets = this.props[0].map( (tweet) => { + return ( + +
+
{tweet.id}
+ {`${tweet.tweeted_on}`} +
+

{tweet.content}

+ Created By +
+ ); + }); + + return ( + +
+ {tweets} +
+
+ ); + } +} + +module.exports = Home; diff --git a/views/layouts/default.jsx b/views/layouts/default.jsx new file mode 100644 index 0000000..594072c --- /dev/null +++ b/views/layouts/default.jsx @@ -0,0 +1,39 @@ +var React = require('react'); + +class DefaultLayout extends React.Component { + render() { + + + + return ( + + + + + + + +
+ + {this.props.children} + + + + + + + +
+ + + + + + ); + } +} + +module.exports = DefaultLayout; \ No newline at end of file From e296de71913fac15c25d9da932a6997328982b32 Mon Sep 17 00:00:00 2001 From: hongchiong Date: Sun, 13 Jan 2019 20:29:27 +0800 Subject: [PATCH 2/5] tweet box jumbotron. signin/signout buttons --- index.js | 40 ++++++++++++++++++++++----- views/home.jsx | 55 ++++++++++++++++++++++++++++++++----- views/layouts/default.jsx | 57 ++++++++++++++++++++++++++++++++------- 3 files changed, 130 insertions(+), 22 deletions(-) diff --git a/index.js b/index.js index c03da7f..5f4b442 100644 --- a/index.js +++ b/index.js @@ -44,7 +44,7 @@ app.engine('jsx', reactEngine); // SHOW ALL TWEETS //============================================================== app.get('/', (req, res) => { - let query = "SELECT * FROM tweets;"; + let query = "SELECT * FROM tweets INNER JOIN users ON (tweets.author_id = users.id);"; pool.query(query, (err, result) => { if (err) { @@ -52,16 +52,44 @@ app.get('/', (req, res) => { res.send( 'query error' ); } else { let resultArr = [result.rows]; - res.render('home', resultArr); - // res.send(resultArr); + resultArr.push(req.cookies['loggedIn']); + + if (req.cookies['loggedIn']) { + query = `SELECT * FROM users WHERE name='${req.cookies['name']}'`; + pool.query(query, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + resultArr.push(result.rows); + console.log(resultArr); + res.render('home', resultArr); + } + }) + } else { + console.log(resultArr); + res.render('home', resultArr); + } } }); }); - +// //============================================================== -app.get('/users/new', (req, res) => { - res.render('user/newuser'); +app.post('/users/new', (req, res) => { + const values = [req.body.name, req.body.password]; + let query = "INSERT INTO users (name, password) VALUES ($1, $2)"; + + pool.query(query, values, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + res.cookie('loggedIn', true); + res.cookie('name', req.body.name); + res.redirect('/'); + } + }); }); app.post('/users', (req, res) => { diff --git a/views/home.jsx b/views/home.jsx index b01b1d8..9c0ad7f 100644 --- a/views/home.jsx +++ b/views/home.jsx @@ -4,21 +4,64 @@ var DefaultLayout = require('./layouts/default'); class Home extends React.Component { render() { - const tweets = this.props[0].map( (tweet) => { + const buttonsFalse = () => { return ( - +
+ + +
+ ); + }; + const buttonsTrue = () => { + return ( +
+ +
+ ); + }; + + const tweetForm = () => { + return ( +
+

{this.props[2][0].name}

+
+
+
+ ); + }; + + const tweets = this.props[0].map( (tweet, i) => { + return ( + +
+
{i + 1}
+
+
+

{tweet.content}

+
-
{tweet.id}
+ Tweeted By: {tweet.name} {`${tweet.tweeted_on}`}
-

{tweet.content}

- Created By
); }); return ( - + +
+

Welcome to Tweedr!

+ {(this.props[1] == 'true') ? tweetForm() : null} +
{tweets}
diff --git a/views/layouts/default.jsx b/views/layouts/default.jsx index 594072c..d5e2711 100644 --- a/views/layouts/default.jsx +++ b/views/layouts/default.jsx @@ -3,8 +3,6 @@ var React = require('react'); class DefaultLayout extends React.Component { render() { - - return ( @@ -15,17 +13,56 @@ class DefaultLayout extends React.Component {
- {this.props.children} - - - - - + {this.props.children} + +
From b11652ca2992cd37ad02db29c9820806219c022a Mon Sep 17 00:00:00 2001 From: hongchiong Date: Sun, 13 Jan 2019 23:29:27 +0800 Subject: [PATCH 3/5] user logins. add tweets --- index.js | 97 +++++++++++++++++++++++++++------------ views/home.jsx | 19 ++++---- views/layouts/default.jsx | 8 ++-- 3 files changed, 83 insertions(+), 41 deletions(-) diff --git a/index.js b/index.js index 5f4b442..7c57bf5 100644 --- a/index.js +++ b/index.js @@ -44,7 +44,7 @@ app.engine('jsx', reactEngine); // SHOW ALL TWEETS //============================================================== app.get('/', (req, res) => { - let query = "SELECT * FROM tweets INNER JOIN users ON (tweets.author_id = users.id);"; + let query = "SELECT * FROM tweets INNER JOIN users ON (tweets.author_id = users.id) ORDER BY tweeted_on DESC;"; pool.query(query, (err, result) => { if (err) { @@ -55,60 +55,99 @@ app.get('/', (req, res) => { resultArr.push(req.cookies['loggedIn']); if (req.cookies['loggedIn']) { - query = `SELECT * FROM users WHERE name='${req.cookies['name']}'`; + query = `SELECT * FROM users WHERE name='${req.cookies['name']}';`; pool.query(query, (err, result) => { if (err) { console.error('query error:', err.stack); res.send( 'query error' ); } else { resultArr.push(result.rows); - console.log(resultArr); res.render('home', resultArr); } }) } else { - console.log(resultArr); res.render('home', resultArr); } } }); }); -// +//SIGN UP SIGN IN SIGN OUT //============================================================== app.post('/users/new', (req, res) => { - const values = [req.body.name, req.body.password]; - let query = "INSERT INTO users (name, password) VALUES ($1, $2)"; + switch (req.body.func) { + case 'signin': + let query = `SELECT * FROM users WHERE name='${req.body.name}'`; + pool.query(query, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + if ( result.rows.length === 0 ) { + res.redirect('/'); + } else { + const user = result.rows[0]; + let password = user.password; + if (password == req.body.password) { + res.cookie('loggedIn', true); + res.cookie('name', req.body.name); + res.redirect('/'); + } else { + res.redirect('/'); + } + } + } + }); + break; + + case 'signout': + res.clearCookie('loggedIn'); + res.clearCookie('name'); + res.redirect('/'); + break; + + case 'signup': + const values = [req.body.name, req.body.password]; + let text = "INSERT INTO users (name, password) VALUES ($1, $2)"; + + pool.query(text, values, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + res.cookie('loggedIn', true); + res.cookie('name', req.body.name); + res.redirect('/'); + } + }); + break; + } +}); + +//CREATE TWEET +//============================================================== +app.post('/', (req, res) => { + let query = `SELECT * FROM users WHERE name='${req.cookies['name']}';`; - pool.query(query, values, (err, result) => { + pool.query(query, (err, result) => { if (err) { console.error('query error:', err.stack); res.send( 'query error' ); } else { - res.cookie('loggedIn', true); - res.cookie('name', req.body.name); - res.redirect('/'); + let query =`INSERT INTO tweets (content, author_id) VALUES ('${req.body.tweet}', ${result.rows[0].id})`; + + pool.query(query, (err, result) => { + if (err) { + console.error('query error:', err.stack); + res.send( 'query error' ); + } else { + res.redirect('/'); + } + }); } }); }); -app.post('/users', (req, res) => { - - const queryString = 'INSERT INTO users (name, password) VALUES ($1, $2)'; - const values = [ - req.body.name, - req.body.password - ]; - - // execute query - pool.query(queryString, values, (error, queryResult) => { - //res.redirect('/'); - res.send('user created'); - }); -}); - - - @@ -127,4 +166,4 @@ let onClose = function(){ }) }; process.on('SIGTERM', onClose); -process.on('SIGINT', onClose); +process.on('SIGINT', onClose); \ No newline at end of file diff --git a/views/home.jsx b/views/home.jsx index 9c0ad7f..3292909 100644 --- a/views/home.jsx +++ b/views/home.jsx @@ -18,11 +18,10 @@ class Home extends React.Component { }; const buttonsTrue = () => { return ( -
- -
+
+ + +
); }; @@ -31,10 +30,12 @@ class Home extends React.Component {

{this.props[2][0].name}


-
- - Learn more -
+
+
+ + +
+
); }; diff --git a/views/layouts/default.jsx b/views/layouts/default.jsx index d5e2711..9f6c5f3 100644 --- a/views/layouts/default.jsx +++ b/views/layouts/default.jsx @@ -28,10 +28,11 @@ class DefaultLayout extends React.Component { -
+