From d926bea55f7eee12cd1b18d00a9254f57f303eb0 Mon Sep 17 00:00:00 2001 From: Benjamin Soung Date: Sat, 8 Jul 2017 00:35:45 -0400 Subject: [PATCH 1/5] finished initial first page withcss and jquery complete --- .gitignore | 1 + app.js | 65 +++++++++++++++ bin/www | 90 ++++++++++++++++++++ npm-debug.log | 48 +++++++++++ package.json | 19 +++++ public/javascripts/script.js | 78 ++++++++++++++++++ public/stylesheets/style.css | 154 +++++++++++++++++++++++++++++++++++ routes/index.js | 9 ++ routes/users.js | 9 ++ utils/APIManager.js | 45 ++++++++++ utils/index.js | 5 ++ views/error.hbs | 3 + views/index.hbs | 45 ++++++++++ views/layout.hbs | 17 ++++ 14 files changed, 588 insertions(+) create mode 100644 .gitignore create mode 100644 app.js create mode 100755 bin/www create mode 100644 npm-debug.log create mode 100644 package.json create mode 100644 public/javascripts/script.js create mode 100644 public/stylesheets/style.css create mode 100644 routes/index.js create mode 100644 routes/users.js create mode 100644 utils/APIManager.js create mode 100644 utils/index.js create mode 100644 views/error.hbs create mode 100644 views/index.hbs create mode 100644 views/layout.hbs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..096746c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/app.js b/app.js new file mode 100644 index 0000000..1b1f53f --- /dev/null +++ b/app.js @@ -0,0 +1,65 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); +var utils = require('./utils'); + +var index = require('./routes/index'); +var users = require('./routes/users'); + +var app = express(); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'hbs'); + +// testing +// const data = { sponsorID: "" }; +// let legislators = utils.APIManager.getLegislators(10010); + +// legislators +// .then(function(res) { +// console.log(res.results); +// }) + +// let votes = utils.APIManager.getVotes('M000087'); +// votes.then(function(res) { console.log(res.results) }).catch(function(err) {console.error(err)}) + +// let bill = utils.APIManager.getBill('hr3003-115'); +// bill.then(function(res) {console.log(res)}) + + +// https://congress.api.sunlightfoundation.com/votes?fields=roll_id,result,voter_ids.A000055 + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', index); +app.use('/users', users); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handler +app.use(function(err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message; + res.locals.error = req.app.get('env') === 'development' ? err : {}; + + // render the error page + res.status(err.status || 500); + res.render('error'); +}); + +module.exports = app; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..22f988a --- /dev/null +++ b/bin/www @@ -0,0 +1,90 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('project-what-have-you-done:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..9c50cf0 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,48 @@ +0 info it worked if it ends with ok +1 verbose cli [ '/Users/benjaminsoung/.nvm/versions/node/v7.0.0/bin/node', +1 verbose cli '/Users/benjaminsoung/.nvm/versions/node/v7.0.0/bin/npm', +1 verbose cli 'run', +1 verbose cli 'start' ] +2 info using npm@4.0.5 +3 info using node@v7.0.0 +4 verbose run-script [ 'prestart', 'start', 'poststart' ] +5 info lifecycle project-what-have-you-done@0.0.0~prestart: project-what-have-you-done@0.0.0 +6 silly lifecycle project-what-have-you-done@0.0.0~prestart: no script for prestart, continuing +7 info lifecycle project-what-have-you-done@0.0.0~start: project-what-have-you-done@0.0.0 +8 verbose lifecycle project-what-have-you-done@0.0.0~start: unsafe-perm in lifecycle true +9 verbose lifecycle project-what-have-you-done@0.0.0~start: PATH: /Users/benjaminsoung/.nvm/versions/node/v7.0.0/lib/node_modules/npm/bin/node-gyp-bin:/Users/benjaminsoung/web-dev/viking/project_what_have_you_done/node_modules/.bin:/Users/benjaminsoung/.rvm/gems/ruby-2.4.0/bin:/Users/benjaminsoung/.rvm/gems/ruby-2.4.0@global/bin:/Users/benjaminsoung/.rvm/rubies/ruby-2.4.0/bin:/Users/benjaminsoung/.nvm/versions/node/v7.0.0/bin:/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/benjaminsoung/bin:/Users/benjaminsoung/.rvm/bin +10 verbose lifecycle project-what-have-you-done@0.0.0~start: CWD: /Users/benjaminsoung/web-dev/viking/project_what_have_you_done +11 silly lifecycle project-what-have-you-done@0.0.0~start: Args: [ '-c', 'node ./bin/www' ] +12 silly lifecycle project-what-have-you-done@0.0.0~start: Returned: code: 1 signal: null +13 info lifecycle project-what-have-you-done@0.0.0~start: Failed to exec start script +14 verbose stack Error: project-what-have-you-done@0.0.0 start: `node ./bin/www` +14 verbose stack Exit status 1 +14 verbose stack at EventEmitter. (/Users/benjaminsoung/.nvm/versions/node/v7.0.0/lib/node_modules/npm/lib/utils/lifecycle.js:279:16) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at EventEmitter.emit (events.js:191:7) +14 verbose stack at ChildProcess. (/Users/benjaminsoung/.nvm/versions/node/v7.0.0/lib/node_modules/npm/lib/utils/spawn.js:40:14) +14 verbose stack at emitTwo (events.js:106:13) +14 verbose stack at ChildProcess.emit (events.js:191:7) +14 verbose stack at maybeClose (internal/child_process.js:877:16) +14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) +15 verbose pkgid project-what-have-you-done@0.0.0 +16 verbose cwd /Users/benjaminsoung/web-dev/viking/project_what_have_you_done +17 error Darwin 16.4.0 +18 error argv "/Users/benjaminsoung/.nvm/versions/node/v7.0.0/bin/node" "/Users/benjaminsoung/.nvm/versions/node/v7.0.0/bin/npm" "run" "start" +19 error node v7.0.0 +20 error npm v4.0.5 +21 error code ELIFECYCLE +22 error project-what-have-you-done@0.0.0 start: `node ./bin/www` +22 error Exit status 1 +23 error Failed at the project-what-have-you-done@0.0.0 start script 'node ./bin/www'. +23 error Make sure you have the latest version of node.js and npm installed. +23 error If you do, this is most likely a problem with the project-what-have-you-done package, +23 error not with npm itself. +23 error Tell the author that this fails on your system: +23 error node ./bin/www +23 error You can get information on how to open an issue for this project with: +23 error npm bugs project-what-have-you-done +23 error Or if that isn't available, you can get their info via: +23 error npm owner ls project-what-have-you-done +23 error There is likely additional logging output above. +24 verbose exit [ 1, true ] diff --git a/package.json b/package.json new file mode 100644 index 0000000..d5ba539 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "project-what-have-you-done", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "nodemon ./bin/www" + }, + "dependencies": { + "body-parser": "~1.17.1", + "cookie-parser": "~1.4.3", + "debug": "~2.6.3", + "express": "~4.15.2", + "hbs": "~4.0.1", + "morgan": "~1.8.1", + "nodemon": "^1.11.0", + "serve-favicon": "~2.4.2", + "superagent": "^3.5.2" + } +} diff --git a/public/javascripts/script.js b/public/javascripts/script.js new file mode 100644 index 0000000..c6cb720 --- /dev/null +++ b/public/javascripts/script.js @@ -0,0 +1,78 @@ +$(() => { + function init() { + input.detectKey(); + } + + const input = { + + detectKey: function() { + let inputBoxes = $('.zip-input-box').children(); + let i = 0; + let selectedBox = inputBoxes[i]; + let inner = $(selectedBox).children()[0]; + + $(document).keydown(function(e) { + let selectedKey; + if (e.keyCode >= 48 && e.keyCode <= 57 && i <= 4) { + selectedKey = e.key; + + if (selectedKey && i <= 5) { + + $(selectedBox).removeClass('active-number-box'); + + $(inner).removeClass() + $(inner).text(selectedKey); + + i++ + + selectedBox = inputBoxes[i]; + inner = $(selectedBox).children()[0]; + + $(selectedBox).addClass('active-number-box'); + $(inner).addClass('mark-across active-mark') + } + } else if (e.keyCode === 8 && i > 0) { + + $(selectedBox).removeClass('active-number-box'); + $(inner).removeClass('active-mark'); + + i--; + + selectedBox = inputBoxes[i]; + inner = $(selectedBox).children()[0]; + + $(selectedBox).addClass('active-number-box'); + + $(inner).text(''); + $(inner).addClass('mark-across active-mark'); + + } + + if (i >= 5) { + let btn = $(''); + + $('.zip-box').addClass('stretch'); + + setTimeout(function(){ + + if ($('.zip-box').hasClass('stretch')) { + $(btn).hide().appendTo('.zip-box').fadeIn(100); + } + }, 200); + + } else { + + $('.submit-btn').fadeOut(200, function() { + $(this).hide().remove(); + }) + $('.zip-box').removeClass('stretch'); + } + + + + }) + } + } + + init(); +}) \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..561fe3b --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,154 @@ +@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); + +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + +body { + font-family: 'Open Sans', sans-serif; + background: #f5f5f5; +} + +.box-container { + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 100vh; +} + +.box { + width: 500px; + height: 400px; +} + +.title-box { + display: flex; + justify-content: center; + align-items: center; + margin: 0 auto; + background-color: #ebff00; + height: 50px; + width: 73%; +} + +.title-tag-box { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + margin: 0 auto; + margin-top: 10px; + height: 80px; + width: 73%; + font-size: 1.6em; +} + +.sm-txt-box { + height: 20px; + width: 100%; + color: #7b7b7b; + text-align: center; + margin-top: 10px; +} + +.zip-box { + position: relative; + background-color: #fefff8; + width: 320px; + height: 130px; + border: 1px solid #cccccc; + margin: 0 auto; + margin-top: 30px; + transition: .5s; +} + +.zip-box p { + font-size: 1.4em; +} + +.zip-title { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + margin-top: 10px; + width: 100%; + height: 30px; +} + +.zip-input-box { + position: absolute; + top: 35px; + display: flex; + justify-content: space-around; + align-items: center; + padding-left: 20px; + padding-right: 20px; + width: 100%; + height: 90px; +} + + +.number-box { + display: flex; + justify-content: center; + align-items: center; + font-weight: bold; + font-size: 2em; + width: 40px; + height: 55px; + border: 1px solid #cccccc; + border-radius: 13px; +} + +.mark-across { + width: 15px; + height: 1%; + border: 2px solid #808080; +} + +.active-mark { + border: 2px solid #000000; +} + +.active-number-box { + background-color: #ebff00; +} + +.bold-text { + font-weight: bold; +} + +.submit-btn { + position: absolute; + top: 125px; + left: 130px; + padding: 7px 17px; + border-radius: 5px; + background-color: #ebff00; + font-weight: bold; + font-size: 13px; + border: 1px solid #cccccc; + +} + +.stretch { + height: 180px; +} + + + + + + + + + + + + + + diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..647d796 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'What Have You Done?' }); +}); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/utils/APIManager.js b/utils/APIManager.js new file mode 100644 index 0000000..31dbd94 --- /dev/null +++ b/utils/APIManager.js @@ -0,0 +1,45 @@ +var superagent = require('superagent'); + +// https://congress.api.sunlightfoundation.com/votes?fields=chamber,bill_id,voter_ids.M000087 +// https://congress.api.sunlightfoundation.com/bills?fields=urls.govtrack,official_title&bill_id=hr3003-115 + +var baseURI = 'https://congress.api.sunlightfoundation.com'; // /legislators/locate // bioguide_id + +module.exports = { + getLegislators: function(zipCode) { + return this._get('legislators/locate', { zip: zipCode }); + }, + + // M000087 + getVotes: function(sponsorID) { + let id = `voter_ids.${sponsorID}`; + + return this._get('votes', { fields: `chamber,bill_id,${id}` }); + }, + + getBill: function(billID) { + return this._get('bills', { fields: 'urls.govtrack,official_title', bill_id: billID }); + }, + + _get: function(endpoint, queries={}) { + return new Promise(function(resolve, reject) { + let endURI = `${baseURI}/${endpoint}` + + superagent + .get(endURI) + .set('Accept', 'application/json') + .query(queries) + .end(function(err, res) { + if (err) { + reject(err); + return; + } + + let parsedData = JSON.parse(res.text); + + resolve(parsedData); + }) + + }) + } +} \ No newline at end of file diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..5e4771b --- /dev/null +++ b/utils/index.js @@ -0,0 +1,5 @@ +var APIManager = require('./APIManager'); + +module.exports = { + APIManager: APIManager +} \ No newline at end of file diff --git a/views/error.hbs b/views/error.hbs new file mode 100644 index 0000000..0659765 --- /dev/null +++ b/views/error.hbs @@ -0,0 +1,3 @@ +

{{message}}

+

{{error.status}}

+
{{error.stack}}
diff --git a/views/index.hbs b/views/index.hbs new file mode 100644 index 0000000..ca314ca --- /dev/null +++ b/views/index.hbs @@ -0,0 +1,45 @@ +
+
+

{{title}}

+
+ +
+

Discover the voting records

+

of your local representatives

+
+ +
+

Then pester their offices until their views reflect yours!

+
+ +
+
+

Enter Your Zip Code

+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+ + diff --git a/views/layout.hbs b/views/layout.hbs new file mode 100644 index 0000000..2ff4f89 --- /dev/null +++ b/views/layout.hbs @@ -0,0 +1,17 @@ + + + + {{title}} + + + +
+ {{{body}}} +
+ + + + From f661bc616cdbcf52506f64cfd0dcb644807a8ccc Mon Sep 17 00:00:00 2001 From: Benjamin Soung Date: Thu, 13 Jul 2017 14:59:26 -0400 Subject: [PATCH 2/5] changes due to api shutdown, created dummy data and passed zipcode info --- app.js | 26 ++++++------- dummy/dummy.json | 37 ++++++++++++++++++ public/javascripts/script.js | 65 ++++++++++++++++++++++++++----- public/stylesheets/style.css | 75 +++++++++++++++++++++++++++++++++++- routes/api.js | 10 +++++ routes/people.js | 14 +++++++ routes/results.js | 24 ++++++++++++ routes/users.js | 9 ----- utils/APIManager.js | 34 +++++----------- utils/APIManagerOld.js | 45 ++++++++++++++++++++++ views/index.hbs | 1 + views/layout.hbs | 6 +-- views/people.hbs | 11 ++++++ views/results.hbs | 59 ++++++++++++++++++++++++++++ 14 files changed, 353 insertions(+), 63 deletions(-) create mode 100644 dummy/dummy.json create mode 100644 routes/api.js create mode 100644 routes/people.js create mode 100644 routes/results.js delete mode 100644 routes/users.js create mode 100644 utils/APIManagerOld.js create mode 100644 views/people.hbs create mode 100644 views/results.hbs diff --git a/app.js b/app.js index 1b1f53f..b048817 100644 --- a/app.js +++ b/app.js @@ -7,7 +7,9 @@ var bodyParser = require('body-parser'); var utils = require('./utils'); var index = require('./routes/index'); -var users = require('./routes/users'); +var results = require('./routes/results'); +var api = require('./routes/api'); +var people = require('./routes/people'); var app = express(); @@ -15,23 +17,17 @@ var app = express(); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hbs'); + // testing -// const data = { sponsorID: "" }; -// let legislators = utils.APIManager.getLegislators(10010); +// let reps = utils.APIManager.get('http://localhost:3000/api/reps'); -// legislators +// reps // .then(function(res) { -// console.log(res.results); -// }) - -// let votes = utils.APIManager.getVotes('M000087'); -// votes.then(function(res) { console.log(res.results) }).catch(function(err) {console.error(err)}) - -// let bill = utils.APIManager.getBill('hr3003-115'); -// bill.then(function(res) {console.log(res)}) +// }) +// .catch(function(res) { -// https://congress.api.sunlightfoundation.com/votes?fields=roll_id,result,voter_ids.A000055 +// }) // uncomment after placing your favicon in /public //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); @@ -42,7 +38,9 @@ app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', index); -app.use('/users', users); +app.use('/results', results); +app.use('/people', people); +app.use('/api', api); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/dummy/dummy.json b/dummy/dummy.json new file mode 100644 index 0000000..efe1453 --- /dev/null +++ b/dummy/dummy.json @@ -0,0 +1,37 @@ +{ + "results": { + + "house": [ + { + "name": "Ted Lieu", + "party": "Democrat", + "picture": "https://yt3.ggpht.com/-rpKz1kT8zdQ/AAAAAAAAAAI/AAAAAAAAAAA/tJqE89_Yiro/s100-c-k-no-mo-rj-c0xffffff/photo.jpg" + }, + { + "name": "Brad J. Sherman", + "party": "Democrat", + "picture": "https://media.licdn.com/mpr/mpr/shrink_100_100/p/4/005/09e/215/3c3c3d6.jpg" + }, + { + "name": "Adam B. Schiff", + "party": "Democrat", + "picture": "https://yt3.ggpht.com/-4AJyR4X5VhA/AAAAAAAAAAI/AAAAAAAAAAA/nvH6cIGxgZE/s100-c-k-no-mo-rj-c0xffffff/photo.jpg" + } + ], + + "senate": [ + { + "name": "Kamala Harris", + "party": "Democrat", + "picture": "https://www.aspenideas.org/sites/default/files/styles/thumbnail/public/pictures/people/Kamala_Harris.jpeg" + }, + { + "name": "Dianne Feinstein", + "party": "Democrat", + "picture": "https://i2.wp.com/momocrats.com/wp-content/uploads/catablog/thumbnails/DianneFeinstein.jpg?w=838" + } + ] + + } + +} diff --git a/public/javascripts/script.js b/public/javascripts/script.js index c6cb720..43d7153 100644 --- a/public/javascripts/script.js +++ b/public/javascripts/script.js @@ -1,25 +1,31 @@ $(() => { function init() { - input.detectKey(); + app.detectKey(); + app.searchZip(); + app.displayZip(); } - const input = { + const app = { + zipCode: '', detectKey: function() { let inputBoxes = $('.zip-input-box').children(); let i = 0; let selectedBox = inputBoxes[i]; let inner = $(selectedBox).children()[0]; + let zipCode = ''; $(document).keydown(function(e) { let selectedKey; + if (e.keyCode >= 48 && e.keyCode <= 57 && i <= 4) { selectedKey = e.key; if (selectedKey && i <= 5) { - $(selectedBox).removeClass('active-number-box'); + zipCode += selectedKey; + $(inner).removeClass() $(inner).text(selectedKey); @@ -31,11 +37,13 @@ $(() => { $(selectedBox).addClass('active-number-box'); $(inner).addClass('mark-across active-mark') } - } else if (e.keyCode === 8 && i > 0) { + } else if (e.keyCode === 8 && i > 0) { $(selectedBox).removeClass('active-number-box'); $(inner).removeClass('active-mark'); + zipCode = zipCode.slice(0, -1); + i--; selectedBox = inputBoxes[i]; @@ -45,34 +53,71 @@ $(() => { $(inner).text(''); $(inner).addClass('mark-across active-mark'); - } if (i >= 5) { let btn = $(''); + + app.zipCode = zipCode; $('.zip-box').addClass('stretch'); setTimeout(function(){ - if ($('.zip-box').hasClass('stretch')) { $(btn).hide().appendTo('.zip-box').fadeIn(100); } }, 200); } else { - $('.submit-btn').fadeOut(200, function() { $(this).hide().remove(); }) + $('.zip-box').removeClass('stretch'); } + }); + }, - - + searchZip: function() { + $('.zip-box').on('click', '.submit-btn', function() { + window.location.href = `/results/${app.zipCode}`; }) + }, + + displayZip: function() { + let zipCode = window.location.href.split('/')[4]; + + let boxOne = $('.sm-zip-box').children()[0]; + let boxTwo = $('.sm-zip-box').children()[1]; + let boxThree = $('.sm-zip-box').children()[2]; + let boxFour = $('.sm-zip-box').children()[3]; + let boxFive = $('.sm-zip-box').children()[4]; + + console.log(window.location.href.split('/')); + + for (let i = 0; i <= 4; i++) { + let box = $('.sm-zip-box').children()[i]; + let number = zipCode[i]; + + $(box).text(number); + // console.log(number); + // console.log(box); + } } } init(); -}) \ No newline at end of file +}) + + + + + + + + + + + + + diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 561fe3b..854d354 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -11,6 +11,11 @@ body { background: #f5f5f5; } +a { + text-decoration: none; + color: black; +} + .box-container { display: flex; justify-content: center; @@ -24,6 +29,12 @@ body { height: 400px; } +.box-wide { + width: 600px; + height: 100%; + padding-top: 50px; +} + .title-box { display: flex; justify-content: center; @@ -31,7 +42,7 @@ body { margin: 0 auto; background-color: #ebff00; height: 50px; - width: 73%; + width: 370px; } .title-tag-box { @@ -54,6 +65,17 @@ body { margin-top: 10px; } +.sm-zip-box { + display: flex; + justify-content: space-around; + align-items: center; + padding-left: 35px; + padding-right: 35px; + width: 200px; + height: 50px; + margin: 0 auto; +} + .zip-box { position: relative; background-color: #fefff8; @@ -91,6 +113,14 @@ body { height: 90px; } +.sm-number-box { + text-align: center; + width: 18px; + height: 25px; + background-color: white; + border-radius: 3px; + border: 1px solid #cccccc; +} .number-box { display: flex; @@ -118,6 +148,48 @@ body { background-color: #ebff00; } +.group-title { + color: #7a7a7a; + margin-top: 20px; + font-size: 1.3em; + text-align: center; +} + +.rep-group-box { + width: 600px; + height: 300px; + margin: 0 auto; + margin-top: 20px; +} + +.rep-box { + display: flex; + margin-bottom: 30px; + width: 100%; + height: 80px; + +} + +.photo-box { + width: 13%; + height: 100%; + border-radius: 99px; +} + +.photo-box img { + width: 80px; + border-radius: 99px; +} + +.name-box { + display: flex; + flex-direction: column; + justify-content: center; + padding-left: 15px; + width: 80%; + height: 100%; +} + .bold-text { font-weight: bold; } @@ -132,7 +204,6 @@ body { font-weight: bold; font-size: 13px; border: 1px solid #cccccc; - } .stretch { diff --git a/routes/api.js b/routes/api.js new file mode 100644 index 0000000..24b6208 --- /dev/null +++ b/routes/api.js @@ -0,0 +1,10 @@ +var express = require('express'); +var router = express.Router(); +var data = require('../dummy/dummy.json'); + +/* GET home page. */ +router.get('/reps', function(req, res, next) { + res.json(data); +}); + +module.exports = router; diff --git a/routes/people.js b/routes/people.js new file mode 100644 index 0000000..ef4eee4 --- /dev/null +++ b/routes/people.js @@ -0,0 +1,14 @@ +var express = require('express'); +var router = express.Router(); +var utils = require('../utils'); + +/* GET users listing. */ +router.get('/:person', function(req, res, next) { + let data = { + title: 'What Have You Done?' + } + + res.render('people', data); +}); + +module.exports = router; diff --git a/routes/results.js b/routes/results.js new file mode 100644 index 0000000..0fe89e4 --- /dev/null +++ b/routes/results.js @@ -0,0 +1,24 @@ +var express = require('express'); +var router = express.Router(); +var utils = require('../utils'); + +/* GET users listing. */ +router.get('/:zipcode', function(req, res, next) { + let data = { + title: 'What Have You Done?', + zipcode: req.params.zipcode + } + + utils.APIManager.get('http://localhost:3000/api/reps') + .then(function(info) { + data['results'] = info.results; + + console.log(data, 'data'); + res.render('results', data); + }) + .catch(function(err) { + console.log(err) + }); +}); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js deleted file mode 100644 index 623e430..0000000 --- a/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router; diff --git a/utils/APIManager.js b/utils/APIManager.js index 31dbd94..8078b88 100644 --- a/utils/APIManager.js +++ b/utils/APIManager.js @@ -1,32 +1,17 @@ -var superagent = require('superagent'); +/* + For Dummy Data + */ -// https://congress.api.sunlightfoundation.com/votes?fields=chamber,bill_id,voter_ids.M000087 -// https://congress.api.sunlightfoundation.com/bills?fields=urls.govtrack,official_title&bill_id=hr3003-115 +var superagent = require('superagent'); -var baseURI = 'https://congress.api.sunlightfoundation.com'; // /legislators/locate // bioguide_id +// var baseURI = '/api/reps'; module.exports = { - getLegislators: function(zipCode) { - return this._get('legislators/locate', { zip: zipCode }); - }, - - // M000087 - getVotes: function(sponsorID) { - let id = `voter_ids.${sponsorID}`; - - return this._get('votes', { fields: `chamber,bill_id,${id}` }); - }, - getBill: function(billID) { - return this._get('bills', { fields: 'urls.govtrack,official_title', bill_id: billID }); - }, - - _get: function(endpoint, queries={}) { + get: function(endpoint, queries={}) { return new Promise(function(resolve, reject) { - let endURI = `${baseURI}/${endpoint}` - superagent - .get(endURI) + .get(endpoint) .set('Accept', 'application/json') .query(queries) .end(function(err, res) { @@ -38,8 +23,7 @@ module.exports = { let parsedData = JSON.parse(res.text); resolve(parsedData); - }) - - }) + }); + }); } } \ No newline at end of file diff --git a/utils/APIManagerOld.js b/utils/APIManagerOld.js new file mode 100644 index 0000000..167e3bb --- /dev/null +++ b/utils/APIManagerOld.js @@ -0,0 +1,45 @@ +/* + NOTE: This was for the Sunlight Labs API that has since been shut down. Leaving work here as notes. + */ + +var superagent = require('superagent'); + +var baseURI = 'https://congress.api.sunlightfoundation.com'; + +module.exports = { + getLegislators: function(zipCode) { + return this._get('legislators/locate', { zip: zipCode }); + }, + + getVotes: function(sponsorID) { + let id = `voter_ids.${sponsorID}`; + + return this._get('votes', { fields: `chamber,bill_id,${id}` }); + }, + + getBill: function(billID) { + return this._get('bills', { fields: 'urls.govtrack,official_title', bill_id: billID }); + }, + + _get: function(endpoint, queries={}) { + return new Promise(function(resolve, reject) { + let endURI = `${baseURI}/${endpoint}` + + superagent + .get(endURI) + .set('Accept', 'application/json') + .query(queries) + .end(function(err, res) { + if (err) { + reject(err); + return; + } + + let parsedData = JSON.parse(res.text); + + resolve(parsedData); + }) + + }) + } +} \ No newline at end of file diff --git a/views/index.hbs b/views/index.hbs index ca314ca..5ab3c05 100644 --- a/views/index.hbs +++ b/views/index.hbs @@ -1,3 +1,4 @@ +

{{title}}

diff --git a/views/layout.hbs b/views/layout.hbs index 2ff4f89..15098f2 100644 --- a/views/layout.hbs +++ b/views/layout.hbs @@ -5,13 +5,13 @@ -
+
{{{body}}} -
+
- + diff --git a/views/people.hbs b/views/people.hbs new file mode 100644 index 0000000..7979160 --- /dev/null +++ b/views/people.hbs @@ -0,0 +1,11 @@ + + + + Results + + +
+

{{title}}

+
+ + \ No newline at end of file diff --git a/views/results.hbs b/views/results.hbs new file mode 100644 index 0000000..c81ee01 --- /dev/null +++ b/views/results.hbs @@ -0,0 +1,59 @@ + + + + Results + + +
+
+

{{title}}

+
+ +
+
+
+
+
+
+
+ +

House

+ +
+ + {{#each results.house as |person|}} + +
+
+ +
+ +
+

{{person.name}}

+

{{person.party}}

+
+
+
+ {{/each}} + +

Senate

+ + {{#each results.senate as |person|}} + +
+
+ +
+ +
+

{{person.name}}

+

{{person.party}}

+
+
+
+ {{/each}} + +
+
+ + \ No newline at end of file From 3d87973aeaea79b3c01df653c275b15d745b724d Mon Sep 17 00:00:00 2001 From: Benjamin Soung Date: Fri, 14 Jul 2017 00:24:16 -0400 Subject: [PATCH 3/5] finished required functionalities for app --- dummy/dummy.json | 166 +++++++++++++++++++++++++++++++++-- public/javascripts/script.js | 29 +++--- public/stylesheets/style.css | 95 +++++++++++++++++++- routes/people.js | 22 ++++- routes/results.js | 1 - views/people.hbs | 55 +++++++++++- 6 files changed, 345 insertions(+), 23 deletions(-) diff --git a/dummy/dummy.json b/dummy/dummy.json index efe1453..290aa21 100644 --- a/dummy/dummy.json +++ b/dummy/dummy.json @@ -5,17 +5,111 @@ { "name": "Ted Lieu", "party": "Democrat", - "picture": "https://yt3.ggpht.com/-rpKz1kT8zdQ/AAAAAAAAAAI/AAAAAAAAAAA/tJqE89_Yiro/s100-c-k-no-mo-rj-c0xffffff/photo.jpg" + "picture": "https://yt3.ggpht.com/-rpKz1kT8zdQ/AAAAAAAAAAI/AAAAAAAAAAA/tJqE89_Yiro/s100-c-k-no-mo-rj-c0xffffff/photo.jpg", + "phone": "(202) 225-3976", + "website": "https://lieu.house.gov/", + "bills": [ + { + "name": "hjres41-115", + "description": "Providing for congressional disapproval under chapter 8 of title 5, United States Codes, of a rule submitted by the Securities and Exchange Commission relating to 'Disclosure of Payments by Resource Extration Issuers'.", + "yes": "", + "no": "1" + }, + + { + "name": "hjres38-115", + "description": "Disapproving the rule submitted by the Department of Interor known as the Stream Protection Rule.", + "yes": "", + "no": "1" + }, + + { + "name": "hr7-115", + "description": "To prohibit taxpayer funded abortions", + "yes": "", + "no": "1" + }, + + { + "name": "s84-115", + "description": "A bill to provide for an exception to a limition against appointment of...", + "yes": "1", + "no": "" + } + ] }, + { "name": "Brad J. Sherman", "party": "Democrat", - "picture": "https://media.licdn.com/mpr/mpr/shrink_100_100/p/4/005/09e/215/3c3c3d6.jpg" + "picture": "https://media.licdn.com/mpr/mpr/shrink_100_100/p/4/005/09e/215/3c3c3d6.jpg", + "phone": "(202) 225-5911", + "website": "https://sherman.house.gov/", + "bills": [ + { + "name": "hjres41-115", + "description": "Providing for congressional disapproval under chapter 8 of title 5, United States Codes, of a rule submitted by the Securities and Exchange Commission relating to 'Disclosure of Payments by Resource Extration Issuers'.", + "yes": "1", + "no": "" + }, + + { + "name": "hjres38-115", + "description": "Disapproving the rule submitted by the Department of Interor known as the Stream Protection Rule.", + "yes": "", + "no": "1" + }, + + { + "name": "hr7-115", + "description": "To prohibit taxpayer funded abortions", + "yes": "1", + "no": "" + }, + + { + "name": "s84-115", + "description": "A bill to provide for an exception to a limition against appointment of...", + "yes": "1", + "no": "" + } + ] }, { "name": "Adam B. Schiff", "party": "Democrat", - "picture": "https://yt3.ggpht.com/-4AJyR4X5VhA/AAAAAAAAAAI/AAAAAAAAAAA/nvH6cIGxgZE/s100-c-k-no-mo-rj-c0xffffff/photo.jpg" + "picture": "https://yt3.ggpht.com/-4AJyR4X5VhA/AAAAAAAAAAI/AAAAAAAAAAA/nvH6cIGxgZE/s100-c-k-no-mo-rj-c0xffffff/photo.jpg", + "phone": "(202) 225-4176", + "website": "https://schiff.house.gov/", + "bills": [ + { + "name": "hjres41-115", + "description": "Providing for congressional disapproval under chapter 8 of title 5, United States Codes, of a rule submitted by the Securities and Exchange Commission relating to 'Disclosure of Payments by Resource Extration Issuers'.", + "yes": "1", + "no": "" + }, + + { + "name": "hjres38-115", + "description": "Disapproving the rule submitted by the Department of Interor known as the Stream Protection Rule.", + "yes": "1", + "no": "" + }, + + { + "name": "hr7-115", + "description": "To prohibit taxpayer funded abortions", + "yes": "", + "no": "1" + }, + + { + "name": "s84-115", + "description": "A bill to provide for an exception to a limition against appointment of...", + "yes": "1", + "no": "" + } + ] } ], @@ -23,12 +117,74 @@ { "name": "Kamala Harris", "party": "Democrat", - "picture": "https://www.aspenideas.org/sites/default/files/styles/thumbnail/public/pictures/people/Kamala_Harris.jpeg" + "picture": "https://www.aspenideas.org/sites/default/files/styles/thumbnail/public/pictures/people/Kamala_Harris.jpeg", + "phone": "(202) 224-3553", + "website": "https://www.harris.senate.gov/", + "bills": [ + { + "name": "hjres41-115", + "description": "Providing for congressional disapproval under chapter 8 of title 5, United States Codes, of a rule submitted by the Securities and Exchange Commission relating to 'Disclosure of Payments by Resource Extration Issuers'.", + "yes": "", + "no": "1" + }, + + { + "name": "hjres38-115", + "description": "Disapproving the rule submitted by the Department of Interor known as the Stream Protection Rule.", + "yes": "", + "no": "1" + }, + + { + "name": "hr7-115", + "description": "To prohibit taxpayer funded abortions", + "yes": "1", + "no": "" + }, + + { + "name": "s84-115", + "description": "A bill to provide for an exception to a limition against appointment of...", + "yes": "", + "no": "1" + } + ] }, { "name": "Dianne Feinstein", "party": "Democrat", - "picture": "https://i2.wp.com/momocrats.com/wp-content/uploads/catablog/thumbnails/DianneFeinstein.jpg?w=838" + "picture": "https://i2.wp.com/momocrats.com/wp-content/uploads/catablog/thumbnails/DianneFeinstein.jpg?w=838", + "phone": "(202) 224-3841", + "website": "https://www.feinstein.senate.gov/public/", + "bills": [ + { + "name": "hjres41-115", + "description": "Providing for congressional disapproval under chapter 8 of title 5, United States Codes, of a rule submitted by the Securities and Exchange Commission relating to 'Disclosure of Payments by Resource Extration Issuers'.", + "yes": "", + "no": "1" + }, + + { + "name": "hjres38-115", + "description": "Disapproving the rule submitted by the Department of Interor known as the Stream Protection Rule.", + "yes": "1", + "no": "" + }, + + { + "name": "hr7-115", + "description": "To prohibit taxpayer funded abortions", + "yes": "", + "no": "1" + }, + + { + "name": "s84-115", + "description": "A bill to provide for an exception to a limition against appointment of...", + "yes": "", + "no": "1" + } + ] } ] diff --git a/public/javascripts/script.js b/public/javascripts/script.js index 43d7153..b694bfa 100644 --- a/public/javascripts/script.js +++ b/public/javascripts/script.js @@ -3,6 +3,7 @@ $(() => { app.detectKey(); app.searchZip(); app.displayZip(); + app.selectPerson(); } const app = { @@ -87,22 +88,24 @@ $(() => { displayZip: function() { let zipCode = window.location.href.split('/')[4]; - let boxOne = $('.sm-zip-box').children()[0]; - let boxTwo = $('.sm-zip-box').children()[1]; - let boxThree = $('.sm-zip-box').children()[2]; - let boxFour = $('.sm-zip-box').children()[3]; - let boxFive = $('.sm-zip-box').children()[4]; + if (zipCode) { + for (let i = 0; i <= 4; i++) { + let box = $('.sm-zip-box').children()[i]; + let number = zipCode[i]; - console.log(window.location.href.split('/')); + $(box).text(number); + } + } + + }, - for (let i = 0; i <= 4; i++) { - let box = $('.sm-zip-box').children()[i]; - let number = zipCode[i]; + selectPerson: function() { + $('.rep-group-box').on('click', '.rep-box', function() { + let nameBox = $(this).children()[1]; + let name = $(nameBox).children()[0].innerHTML; - $(box).text(number); - // console.log(number); - // console.log(box); - } + window.location.href = `/people/${name}`; + }) } } diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 854d354..b3d24aa 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -45,6 +45,15 @@ a { width: 370px; } +.md-title-box { + display: inline-block; + margin: 0 auto; + background-color: #ebff00; + height: 35px; + overflow: scroll; + width: auto; +} + .title-tag-box { display: flex; flex-direction: column; @@ -172,7 +181,7 @@ a { .photo-box { width: 13%; - height: 100%; + margin: 0 auto; border-radius: 99px; } @@ -190,6 +199,90 @@ a { height: 100%; } +.label-box { + width: 300px; + height: 30px; + text-align: center; + margin: 0 auto; +} + +.contact-box { + background-color: white; + width: 260px; + height: 120px; + margin: 0 auto; + border: 1px solid #cccccc; +} + +.contact-box div { + width: 100%; + height: 50%; + padding-top: 5px; + padding-left: 10px; + overflow: scroll; +} + +.contact-box div p { + color: #7e7e82; + font-size: 0.8em; +} + +.phone-box { + width: 100%; + height: 50%; + border: 1px solid black; +} + +.sm-title { + text-align: center; + color: #2d2d2d; +} + +.center-box { + display: flex; + width: 100%; + height: 38px; +} + +.bill-box { + display: flex; + flex-direction: column; + justify-content: space-around; + overflow: wrap; + padding: 10px; + + width: 500px; + height: 100px; + margin: 0 auto; +} + +.bill-box h3 { +} + +.bill-box p { + font-size: 0.8em; +} + +.sm-margin-bt { + margin-bottom: 5px; +} + +.md-margin-bt { + margin-bottom: 20px; +} + +.lg-margin-bt { + margin-bottom: 40px; +} + +.vote-yes { + border: 1px solid green; +} + +.vote-no { + border: 1px solid red; +} + .bold-text { font-weight: bold; } diff --git a/routes/people.js b/routes/people.js index ef4eee4..eab5d6a 100644 --- a/routes/people.js +++ b/routes/people.js @@ -4,11 +4,31 @@ var utils = require('../utils'); /* GET users listing. */ router.get('/:person', function(req, res, next) { + console.log(req.params); + let data = { title: 'What Have You Done?' } - res.render('people', data); + utils.APIManager.get('http://localhost:3000/api/reps') + .then(function(info) { + data['results'] = info.results; + + let selected = data.results.house.filter(person => person.name === req.params.person); + + if (selected.length === 0) { + selected = data.results.senate.filter(person => person.name === req.params.person); + } + + data['results'] = selected[0]; + + (data.results.party === 'Democrat') ? data.results['label'] = 'Democratic Congressperson' : data.results['label'] = 'Republican Congressperson'; + + res.render('people', data); + }) + .catch(function(err) { + console.log(err) + }); }); module.exports = router; diff --git a/routes/results.js b/routes/results.js index 0fe89e4..eaba0ae 100644 --- a/routes/results.js +++ b/routes/results.js @@ -13,7 +13,6 @@ router.get('/:zipcode', function(req, res, next) { .then(function(info) { data['results'] = info.results; - console.log(data, 'data'); res.render('results', data); }) .catch(function(err) { diff --git a/views/people.hbs b/views/people.hbs index 7979160..84cc368 100644 --- a/views/people.hbs +++ b/views/people.hbs @@ -4,8 +4,59 @@ Results -
-

{{title}}

+
+
+

{{title}}

+
+ + +
+ +
+ +
+

{{results.label}}

+
+ +
+
+

{{results.name}}

+
+
+ + +

Contact Info

+ +
+
+

Phone Number

+ {{results.phone}} +
+ +
+

Website

+ {{results.website}} +
+
+ +

Recent Votes

+ + {{#each results.bills as |bill|}} + {{#if bill.yes}} +
+

{{bill.name}}

+

{{bill.description}}

+
+ {{else}} +
+

{{bill.name}}

+

{{bill.description}}

+
+ {{/if}} + {{/each}} +
+ + \ No newline at end of file From a24546ce1cc996110e9da72aac7797d21a5ba23a Mon Sep 17 00:00:00 2001 From: Benjamin Soung Date: Fri, 14 Jul 2017 00:31:06 -0400 Subject: [PATCH 4/5] finished adding return home feature --- public/javascripts/script.js | 7 +++++++ views/results.hbs | 17 ++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/public/javascripts/script.js b/public/javascripts/script.js index b694bfa..24565fb 100644 --- a/public/javascripts/script.js +++ b/public/javascripts/script.js @@ -4,6 +4,7 @@ $(() => { app.searchZip(); app.displayZip(); app.selectPerson(); + app.returnHome(); } const app = { @@ -106,6 +107,12 @@ $(() => { window.location.href = `/people/${name}`; }) + }, + + returnHome: function() { + $('.box-wide').on('click', '.sm-zip-box', function() { + window.location.href = '/'; + }) } } diff --git a/views/results.hbs b/views/results.hbs index c81ee01..cecafb6 100644 --- a/views/results.hbs +++ b/views/results.hbs @@ -9,13 +9,16 @@

{{title}}

-
-
-
-
-
-
-
+ +
+
+
+
+
+
+
+
+

House

From 4b08a0003674783f0f2224cebade33d5a961f005 Mon Sep 17 00:00:00 2001 From: Benjamin Soung Date: Fri, 14 Jul 2017 00:36:38 -0400 Subject: [PATCH 5/5] updated readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb007d2..e5bd05d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # project_what_have_you_done -Build an application to help track the legislative activities of your local representatives. +Built an application to help track the legislative activities of your local representatives. + +## Note: Current required API has been shutdown, so I used dummy json data for the meantime until I find a good API to collect the required data.