From d67fe1cf09de7a6119440f68abdaddba0f8f855e Mon Sep 17 00:00:00 2001 From: smithy545 Date: Thu, 21 Jul 2016 15:35:16 -0400 Subject: [PATCH] fix up formatting; add lots of stuff --- app.js | 7 +- config/admin.js | 160 +++++++++++++++++++++++++++++++++++ models/application.js | 6 +- package.json | 1 + public/stylesheets/style.css | 12 ++- routes/admin.js | 15 ++++ routes/application.js | 32 ++++++- routes/index.js | 3 +- routes/profile.js | 1 + routes/reu.js | 24 ++++-- views/404.jade | 1 + views/application/view.jade | 27 ++++-- views/home.jade | 18 ++-- views/layout.jade | 13 ++- views/profile/edit.jade | 15 +--- views/profile/setup.jade | 10 +-- views/profile/view.jade | 12 +-- views/reu/search.jade | 52 ++++++++---- 18 files changed, 336 insertions(+), 73 deletions(-) create mode 100644 config/admin.js create mode 100644 routes/admin.js create mode 100644 views/404.jade diff --git a/app.js b/app.js index 285e66d..8dc98c3 100644 --- a/app.js +++ b/app.js @@ -8,6 +8,7 @@ var bodyParser = require('body-parser'); var passport = require('passport'); var mongoose = require('mongoose'); var flash = require('connect-flash'); +var mongo_express = require('mongo-express/lib/middleware'); var app = express(); @@ -25,6 +26,7 @@ app.use(express.static(path.join(__dirname, 'public'))); // DB setup require('./config/database.js')(mongoose); +var mongo_express_config = require('./config/admin.js'); // Auth setup require('./config/passport')(passport); @@ -38,12 +40,15 @@ app.use('/', require('./routes/index')); app.use('/profile', require('./routes/profile')); app.use('/reu', require('./routes/reu')); app.use('/apps', require('./routes/application')); +app.use('/admin', require('./routes/admin')); +app.use('/db', mongo_express(mongo_express_config)); + // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; - next(err); + res.render('404', {}); }); // error handlers diff --git a/config/admin.js b/config/admin.js new file mode 100644 index 0000000..584803c --- /dev/null +++ b/config/admin.js @@ -0,0 +1,160 @@ +'use strict'; + +var mongo; +var url = require('url'); + +if (typeof process.env.MONGODB_PORT === 'string') { + var mongoConnection = url.parse(process.env.MONGODB_PORT); + process.env.ME_CONFIG_MONGODB_SERVER = mongoConnection.hostname; + process.env.ME_CONFIG_MONGODB_PORT = mongoConnection.port; +} + +// Accesing Bluemix variable to get MongoDB info +if (process.env.VCAP_SERVICES) { + var dbLabel = 'mongodb-2.4'; + var env = JSON.parse(process.env.VCAP_SERVICES); + if (env[dbLabel]) { + mongo = env[dbLabel][0].credentials; + } +} else { + mongo = { + db: 'reuapp', + host: 'localhost', + password: '', + port: 27017, + ssl: false, + url: 'mongodb://localhost:27017/reuapp', + username: '', + }; +} + +module.exports = { + mongodb: { + server: process.env.ME_CONFIG_MONGODB_SERVER || mongo.host, + port: process.env.ME_CONFIG_MONGODB_PORT || mongo.port, + + //ssl: connect to the server using secure SSL + ssl: process.env.ME_CONFIG_MONGODB_SSL || mongo.ssl, + + //sslValidate: validate mongod server certificate against CA + sslValidate: process.env.ME_CONFIG_MONGODB_SSLVALIDATE || true, + + //sslCA: array of valid CA certificates + sslCA: [], + + //autoReconnect: automatically reconnect if connection is lost + autoReconnect: true, + + //poolSize: size of connection pool (number of connections to use) + poolSize: 4, + + //set admin to true if you want to turn on admin features + //if admin is true, the auth list below will be ignored + //if admin is true, you will need to enter an admin username/password below (if it is needed) + admin: process.env.ME_CONFIG_MONGODB_ENABLE_ADMIN ? process.env.ME_CONFIG_MONGODB_ENABLE_ADMIN.toLowerCase() === 'true' : false, + + // >>>> If you are using regular accounts, fill out auth details in the section below + // >>>> If you have admin auth, leave this section empty and skip to the next section + auth: [ + /* + * Add the name, username, and password of the databases you want to connect to + * Add as many databases as you want! + */ + { + database: process.env.ME_CONFIG_MONGODB_AUTH_DATABASE || mongo.db, + username: process.env.ME_CONFIG_MONGODB_AUTH_USERNAME || mongo.username, + password: process.env.ME_CONFIG_MONGODB_AUTH_PASSWORD || mongo.password, + }, + ], + + // >>>> If you are using an admin mongodb account, or no admin account exists, fill out section below + // >>>> Using an admin account allows you to view and edit all databases, and view stats + + //leave username and password empty if no admin account exists + adminUsername: process.env.ME_CONFIG_MONGODB_ADMINUSERNAME || '', + adminPassword: process.env.ME_CONFIG_MONGODB_ADMINPASSWORD || '', + + //whitelist: hide all databases except the ones in this list (empty list for no whitelist) + whitelist: [], + + //blacklist: hide databases listed in the blacklist (empty list for no blacklist) + blacklist: [], + }, + + site: { + // baseUrl: the URL that mongo express will be located at - Remember to add the forward slash at the start and end! + baseUrl: process.env.ME_CONFIG_SITE_BASEURL || '/', + cookieKeyName: 'mongo-express', + cookieSecret: process.env.ME_CONFIG_SITE_COOKIESECRET || 'cookiesecret', + host: process.env.VCAP_APP_HOST || 'localhost', + port: process.env.VCAP_APP_PORT || 8081, + requestSizeLimit: process.env.ME_CONFIG_REQUEST_SIZE || '50mb', + sessionSecret: process.env.ME_CONFIG_SITE_SESSIONSECRET || 'sessionsecret', + sslCert: process.env.ME_CONFIG_SITE_SSL_CRT_PATH || '', + sslEnabled: process.env.ME_CONFIG_SITE_SSL_ENABLED || false, + sslKey: process.env.ME_CONFIG_SITE_SSL_KEY_PATH || '', + }, + + //set useBasicAuth to true if you want to authehticate mongo-express loggins + //if admin is false, the basicAuthInfo list below will be ignored + //this will be true unless ME_CONFIG_BASICAUTH_USERNAME is set and is the empty string + useBasicAuth: process.env.ME_CONFIG_BASICAUTH_USERNAME !== '', + + basicAuth: { + username: process.env.ME_CONFIG_BASICAUTH_USERNAME || 'admin', + password: process.env.ME_CONFIG_BASICAUTH_PASSWORD || 'pass', + }, + + options: { + // Display startup text on console + console: true, + + //documentsPerPage: how many documents you want to see at once in collection view + documentsPerPage: 10, + + //editorTheme: Name of the theme you want to use for displaying documents + //See http://codemirror.net/demo/theme.html for all examples + editorTheme: process.env.ME_CONFIG_OPTIONS_EDITORTHEME || 'rubyblue', + + // Maximum size of a single property & single row + // Reduces the risk of sending a huge amount of data when viewing collections + maxPropSize: (100 * 1000), // default 100KB + maxRowSize: (1000 * 1000), // default 1MB + + //The options below aren't being used yet + + //cmdType: the type of command line you want mongo express to run + //values: eval, subprocess + // eval - uses db.eval. commands block, so only use this if you have to + // subprocess - spawns a mongo command line as a subprocess and pipes output to mongo express + cmdType: 'eval', + + //subprocessTimeout: number of seconds of non-interaction before a subprocess is shut down + subprocessTimeout: 300, + + //readOnly: if readOnly is true, components of writing are not visible. + readOnly: false, + + //collapsibleJSON: if set to true, jsons will be displayed collapsible + collapsibleJSON: true, + + //collapsibleJSONDefaultUnfold: if collapsibleJSON is set to `true`, this defines default level + // to which JSONs are displayed unfolded; use number or "all" to unfold all levels + collapsibleJSONDefaultUnfold: 1, + }, + + // Specify the default keyname that should be picked from a document to display in collections list. + // Keynames can be specified for every database and collection. + // If no keyname is specified, it defaults to '_id', which is a mandatory field. + // For Example : + // defaultKeyNames{ + // "world_db":{ //Database Name + // "continent":"cont_name", // collection:field + // "country":"country_name", + // "city":"name" + // } + // } + defaultKeyNames: { + + }, +}; diff --git a/models/application.js b/models/application.js index bd027fe..d3fe252 100644 --- a/models/application.js +++ b/models/application.js @@ -1,11 +1,9 @@ var mongoose = require('mongoose'); var appSchema = mongoose.Schema({ - name: String, - location: String, - school: String, - professors: [String], + reuId: String, status: String, + name: String, }); module.exports = mongoose.model('Application', appSchema); diff --git a/package.json b/package.json index 226c5d5..4ed5f63 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "express": "~4.13.4", "express-session": "^1.14.0", "jade": "~1.11.0", + "mongo-express": "^0.30.59", "mongoose": "^4.5.3", "morgan": "~1.7.0", "passport": "^0.3.2", diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 3c719d6..f13371d 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -108,6 +108,14 @@ a { padding: 10px; } -a.topbar-name { - float: right; +ul.reu-info { + list-style: none; +} + +ul.sb-select { + width: 100%; +} + +ul.sb-select li{ + width: 100%; } \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js new file mode 100644 index 0000000..b5f4194 --- /dev/null +++ b/routes/admin.js @@ -0,0 +1,15 @@ +var express = require('express'); +var mongo_express = require('mongo-express/lib/middleware'); +var mongo_express_config = require('../config/admin.js'); + +var User = require('../models/user'); +var Application = require('../models/application'); +var REU = require('../models/reu'); + +var admin = express.Router(); + +admin.use('/', function(req, res, next) { + res.redirect('/db'); +}); + +module.exports = admin; \ No newline at end of file diff --git a/routes/application.js b/routes/application.js index b1bc7b7..bfc7db4 100644 --- a/routes/application.js +++ b/routes/application.js @@ -2,11 +2,11 @@ var express = require('express'); var User = require('../models/user'); var Application = require('../models/application'); +var REU = require('../models/reu'); var apps = express.Router(); apps.get('/', function(req, res) { - //console.log(req.user); var ctx = { user: req.user, tb_highlighted: 'apps', @@ -24,4 +24,34 @@ apps.get('/', function(req, res) { }); }); +apps.post('/apply', function(req, res) { + var id = req.body.reu; + User.findById(req.user._id, function(err, user) { + if(err) throw err; + REU.findById(id, function(err, reu) { + if(err) throw err; + Application.find({reuId: id}, function(err, apps) { + if(err) throw err; + + var app; + if(apps.length > 0) { + app = apps[0]; + } else { + ctx.flash = { type: 'success', message: 'New application created!'}; + app = new Application({ + reuId: id, + status: "unsubmitted", + name: reu.name, + }); + app.save(); + user.applications.push(app._id); + user.save(); + } + + res.redirect('/apps'); + }); + }); + }); +}); + module.exports = apps; \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index 3975fb4..6b7f4da 100644 --- a/routes/index.js +++ b/routes/index.js @@ -42,7 +42,8 @@ router.get('/home', function(req, res) { User.findById(req.user._id, function(err, user) { if(err) throw err; Application.find({ - '_id': { $in: user.applications } + '_id': { $in: user.applications }, + 'status': { $ne : "unsubmitted" }, }, function(err, apps) { if(err) throw err; ctx.applications = apps; diff --git a/routes/profile.js b/routes/profile.js index 604c7b7..a7fa31c 100644 --- a/routes/profile.js +++ b/routes/profile.js @@ -50,6 +50,7 @@ profile.post('/edit', function(req, res) { } user.save(); + ctx.user = user; ctx.flash = { type: 'success', message: "Profile updated successfully!" }; res.render('profile/edit', ctx); }); diff --git a/routes/reu.js b/routes/reu.js index 067f843..5d7724d 100644 --- a/routes/reu.js +++ b/routes/reu.js @@ -10,7 +10,16 @@ reu.get('/', function(req, res) { user: req.user, tb_highlighted: 'reu', }; - res.render('reu/search', ctx); + + REU.find({}, function(err, reus) { + if(err) { + console.log(err); + ctx.results = []; + return res.render('reu/search', ctx); + } + ctx.results = reus; + return res.render('reu/search', ctx); + }); }); reu.post('/search', function(req, res) { @@ -19,13 +28,14 @@ reu.post('/search', function(req, res) { tb_highlighted: 'reu', }; - var searchRXP = new RegExp(req.body.reu_search_info); + var searchRXP = new RegExp(req.body.reu_search_info, 'i'); - REU.find({ - name: searchRXP, - school: searchRXP, - location: searchRXP, - professors: searchRXP + REU.find({ $or:[ + {'name': searchRXP}, + {'school': searchRXP}, + {'location': searchRXP}, + {'professors': searchRXP} + ] }, function(err, reus) { if(err) { console.log(err); diff --git a/views/404.jade b/views/404.jade new file mode 100644 index 0000000..f9294f4 --- /dev/null +++ b/views/404.jade @@ -0,0 +1 @@ +p 404 bitches \ No newline at end of file diff --git a/views/application/view.jade b/views/application/view.jade index 7b62736..2a1e067 100644 --- a/views/application/view.jade +++ b/views/application/view.jade @@ -3,16 +3,33 @@ extends ../layout block title title Applications +block sidemenu + - if(applications.length !== 0) { + nav.sb-nav.navbar.navbar-light + span.sb-header Applications + ul.nav.navbar-nav.sb-select + - var i = 0 + each app in applications + - i++ + li + a(href="#app#{i}") #{app.name} + - } block content - ul.application-list - if(applications.length == 0) { p You have no current applications a(href="/reu") Click here to search for new Research Experience opportunites - } else { - ul.application-list + - var i = 0 each app in applications - - if(app.status != "unsubmitted"){ - li - p= app + - i++ + - if(typeof(active) !== 'undefined' && active === app._id) { + div.content-container(id="app#{i}") + p= app.name + - } else if(typeof(active) === 'undefined' && i === 1) { + div.content-container(id="app#{i}") + p= app.name + - } else { + div.content-container(id="app#{i}" hidden) + p= app.name - } - } \ No newline at end of file diff --git a/views/home.jade b/views/home.jade index 0429fb1..8e9c7ac 100644 --- a/views/home.jade +++ b/views/home.jade @@ -7,10 +7,18 @@ block content ul.application-list - if(applications.length == 0) { p You have no submitted applications - a(href="/reu") Click here to search for new Research Experience opportunites - } else { - ul.application-list - each app in applications - li - p= app + - var i = 0 + div.panel-group(id="application-list") + each app in applications + - i++ + div.panel.panel-default + div.panel-heading + h4.panel-title + a(data-toggle="collapse" data-parent="#application-list" href="#app#{i}") #{app.name} + div.panel-collapse.collapse(id="app#{i}") + div.panel-body + ul.app-info + li + p stuff2 - } \ No newline at end of file diff --git a/views/layout.jade b/views/layout.jade index 1155744..9a5ef9a 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -23,21 +23,28 @@ html a(href="/profile/edit" id="profile") Profile li a(href="/reu" id="reu") REUs - ul(class="nav navbar-nav navbar-right") + ul.nav.navbar-nav.navbar-right + li + p.navbar-text= user.profile.first_name + " " + user.profile.last_name li - //.topbar-name= user.profile.first_name + " " + user.profile.last_name a(href="/logout") Logout div.container.main-outer div.row.main-inner block sidemenu div.content + - if(typeof(flash) !== 'undefined') { + - if(flash.type === 'success') { + div.alert.alert-success + =flash.message + - } + - } block content script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js") script(src="/javascripts/bootstrap.min.js") script(src="/javascripts/init.js") script. - var highlighted = $("#{tb_highlighted}"); + var highlighted = $("##{tb_highlighted}"); highlighted.attr("class", "tb-highlighted"); block script diff --git a/views/profile/edit.jade b/views/profile/edit.jade index 323fc14..bee41bf 100644 --- a/views/profile/edit.jade +++ b/views/profile/edit.jade @@ -6,24 +6,17 @@ block title block sidemenu nav(class="sb-nav navbar navbar-light") span.sb-header Profile - ul(class="nav navbar-nav sb-select") + ul.nav.navbar-nav.sb-select li a(href="#personal") Personal + li a(href="#education") Education + li a(href="#extracurricular") Extracurricular + li a(href="#account") Account block content - - if(typeof(flash) !== 'undefined') { - - if(flash.type === 'invalid') { - div.alert.alert-danger - =flash.message - - } else if(flash.type === 'notice') { - div.alert - =flash.message - - } - - } - a.btn.btn-primary(href="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=77tgqz6flgej2j&redirect_uri=http%3A%2F%2Freu-apply.com%2Fauth%2Flinkedin%2Fcallback&state=0928354") Update from LinkedIn br diff --git a/views/profile/setup.jade b/views/profile/setup.jade index 709065f..18fa2db 100644 --- a/views/profile/setup.jade +++ b/views/profile/setup.jade @@ -5,10 +5,6 @@ block content a.btn.btn-primary(href="https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=77tgqz6flgej2j&redirect_uri=http%3A%2F%2Freu-apply.com%2Fauth%2Flinkedin%2Fcallback&state=0928354") LinkedIn br br - p ...or fill it out yourself - form - fieldset.form-group - label(for="test") Test - input.form-control(type="text" id="test") - - + p ...or + br + a.btn.btn-primary(href="/profile/edit") Fill it out yourself diff --git a/views/profile/view.jade b/views/profile/view.jade index 19af3f2..02a3564 100644 --- a/views/profile/view.jade +++ b/views/profile/view.jade @@ -6,21 +6,17 @@ block title block sidemenu nav(class="sb-nav navbar navbar-light") span.sb-header Profile - ul(class="nav navbar-nav sb-select") + ul.nav.navbar-nav.sb-select li a(href="#personal") Personal + li a(href="#education") Education + li a(href="#extracurricular") Extracurricular + li a(href="#account") Account block content - - if(typeof(flash) !== 'undefined') { - - if(flash.type === 'success') { - div.alert.alert-success - =flash.message - - } - - } - br div.content-container(id="personal") diff --git a/views/reu/search.jade b/views/reu/search.jade index 4c5741d..69c5e7a 100644 --- a/views/reu/search.jade +++ b/views/reu/search.jade @@ -4,27 +4,43 @@ block title title REU block content - - if(typeof(flash) !== 'undefined') { - - if(flash.type === 'success') { - div.alert.alert-success - =flash.message - - } - - } - form.search-reu(action="/reu/search" method="post") div.input-group input.form-control(name="reu_search_info" placeholder="Search for...") span.input-group-btn button.btn.btn-default(type="button") Search - div.reu-search-results - - if(results) { - - if(results.length == 0) { - p No results found :( - - } else { - ul.reu-search-list - each result in results - li - p= result - - } - - } \ No newline at end of file + br + + - if(results) { + - if(results.length == 0) { + p No results found :( + - } else { + - var i = 0 + div.panel-group(id="reu-search-results") + each result in results + - i++ + div.panel.panel-default + div.panel-heading + h4.panel-title + a(data-toggle="collapse" data-parent="#reu-search-results" href="#result#{i}") #{result.name} + div.panel-collapse.collapse(id="result#{i}") + div.panel-body + ul.reu-info + li + p School: #{result.school} + li + p Location: #{result.location} + li + p Professors: + ul.reu-professors + each professor in result.professors + li + p #{professor} + br + br + form(name="apply" method="post" action="/apps/apply") + input(name="reu" type="text" value="#{result._id}" hidden) + button.btn.btn-default Apply + - } + - } \ No newline at end of file