From 24029c27aca6b39af70d6db88e7505ecc90646d5 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 3 Sep 2014 17:13:54 -0400 Subject: endpoints for staff api --- views/staff/index.ejs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 views/staff/index.ejs (limited to 'views/staff/index.ejs') diff --git a/views/staff/index.ejs b/views/staff/index.ejs new file mode 100644 index 0000000..fbe67a7 --- /dev/null +++ b/views/staff/index.ejs @@ -0,0 +1,10 @@ +[[ include _header ]] + +

Staff Area

+ + +[[ include _footer ]] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 95f62d72945acbac295f2342fd51cea9337d7cb7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 3 Sep 2014 18:46:04 -0400 Subject: lastlog --- public/assets/javascripts/ui/site/ProjectList.js | 2 +- public/assets/stylesheets/app.css | 15 ++++--- public/assets/stylesheets/staff.css | 10 +++++ server/lib/auth/index.js | 4 +- server/lib/schemas/User.js | 1 + server/lib/views/staff.js | 52 +++++++++++++++++++++--- views/projects/list-projects.ejs | 2 +- views/staff/_header.ejs | 1 + views/staff/_users.ejs | 15 +++++++ views/staff/_users_recent.ejs | 20 +++++++++ views/staff/index.ejs | 11 ++--- views/staff/users/index.ejs | 2 + 12 files changed, 115 insertions(+), 20 deletions(-) create mode 100644 public/assets/stylesheets/staff.css create mode 100644 views/staff/_users.ejs create mode 100644 views/staff/_users_recent.ejs (limited to 'views/staff/index.ejs') diff --git a/public/assets/javascripts/ui/site/ProjectList.js b/public/assets/javascripts/ui/site/ProjectList.js index d772b20..959aa43 100644 --- a/public/assets/javascripts/ui/site/ProjectList.js +++ b/public/assets/javascripts/ui/site/ProjectList.js @@ -1,7 +1,7 @@ var ProjectList = View.extend({ - el: "#projectList", + el: ".projectList", events: { "mouseenter td.border": 'spinOn', diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 5922ab5..25bcf56 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -161,23 +161,25 @@ h5 { text-align:center; } -.page .profile { +.page.profile { color:white; } -.page table { +.page table.profilepage, +.page table.projectList { width: 100%; border-top: 1px solid; margin: 40px 0 0 0; border-spacing: 0; - clear:nboth; + clear: both; } -.page tr { +.page table.profilepage tr, +.page table.projectList tr { height: 400px; } .page table.showcase { height:70vh; } -.page table td.border { +.page table.projectList td.border { position: relative; border-right: 1px solid; } @@ -191,7 +193,8 @@ iframe.embed { z-index: -1; pointer-events: none; } -.page table td { +.page table.profilepage td, +.page table.projectList td { width: 33.3333%; background-size: cover; background-repeat: no-repeat; diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css new file mode 100644 index 0000000..0208878 --- /dev/null +++ b/public/assets/stylesheets/staff.css @@ -0,0 +1,10 @@ +* { + font-weight: 300; +} +th, b { + font-weight: bold; +} +#users td { + text-align: left; + padding: 2px 5px; +} \ No newline at end of file diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js index 99af9b5..c2275ff 100644 --- a/server/lib/auth/index.js +++ b/server/lib/auth/index.js @@ -111,6 +111,7 @@ var auth = { return info ? res.json(info) : res.redirect("/login"); } + user.last_seen = new Date () user.last_ip = util.ip2num( req.ip ) user.save(function(err, data){ if (err) console.err('error setting ip for user') }) @@ -173,7 +174,8 @@ var auth = { email: email, created_ip: util.ip2num( req.ip ), last_ip: util.ip2num( req.ip ), - created_at: new Date () + created_at: new Date (), + last_seen: new Date (), } new User(data).save(function(err, user){ if (err || ! data) { return res.json({ error: err }) } diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index b64f8fc..180a140 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -64,6 +64,7 @@ var UserSchema = new mongoose.Schema({ isStaff: { type: Boolean, default: false }, created_at: { type: Date }, updated_at: { type: Date }, + last_seen: { type: Date }, created_ip: { type: Number }, last_ip: { type: Number }, }); diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 5dde58d..9643626 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -14,7 +14,7 @@ var User = require('../schemas/User'), var staff = module.exports = { fields: { - user: "_id username displayName created_at updated_at created_ip last_ip", + user: "_id username displayName created_at updated_at last_seen created_ip last_ip", project: "_id name slug created_at updated_at", }, @@ -28,11 +28,15 @@ var staff = module.exports = { middleware: { ensureUsers: function(req, res, next){ + var limit = Math.max( Number(req.params.limit) || 50, 200 ) var offset = Number(req.params.offset) || 0 var sort switch (req.params.sort) { case 'date': - sort = {'date': -1} + sort = {'created_at': -1} + break + case 'lastseen': + sort = {'last_seen': -1} break default: sort = {'username': 1} @@ -42,13 +46,44 @@ var staff = module.exports = { .select(staff.fields.user) .sort(sort) .skip(offset) - .limit(50) + .limit(limit) .exec(function (err, users) { res.locals.users = users.map(staff.helpers.user) next() }) }, + ensureRecentUsers: function(req, res, next){ + var dreq = { params: { sort: 'last_seen', limit: 20, offset: 0 } } + staff.middleware.ensureUsers(dreq, res, next) + }, + + ensureProjects: function(req, res, next){ + var offset = Number(req.params.offset) || 0 + var sort + switch (req.params.sort) { + case 'date': + sort = {'date': -1} + break + default: + sort = {'slug': 1} + break + } + Project.find({}) + .select(staff.fields.project) + .sort(sort) + .skip(offset) + .limit(50) + .exec(function (err, projects) { + res.locals.projects = projects.map(staff.helpers.projects) + next() + }) + }, + + ensureProjectsUsers: function(req, res, next){ + + }, + ensureProfile: function(req, res, next){ var username = req.params.username if (username) { @@ -69,7 +104,6 @@ var staff = module.exports = { }, ensureUsersCount: function(req, res, next){ - if (! res.locals.profile) { return next() } User.count({}, function(err, count){ res.locals.userCount = count || 0 next() @@ -77,7 +111,6 @@ var staff = module.exports = { }, ensureProjectsCount: function(req, res, next){ - if (! res.locals.profile) { return next() } Project.count({}, function(err, count){ res.locals.projectCount = count || 0 next() @@ -136,6 +169,7 @@ var staff = module.exports = { helpers: { user: function(user){ user = user.toObject() + user.last_seen = moment( user.last_seen || user.updated_at || user.created_at ).fromNow() user.created_ip = util.num2ip( user.created_ip ) user.last_ip = util.num2ip( user.last_ip ) return user @@ -151,7 +185,8 @@ var staff = module.exports = { app.get('/staff', middleware.ensureAuthenticated, middleware.ensureIsStaff, - + + staff.middleware.ensureRecentUsers, staff.middleware.ensureUsersCount, staff.middleware.ensureProjectsCount, @@ -180,6 +215,11 @@ var staff = module.exports = { app.get('/staff/projects', middleware.ensureAuthenticated, middleware.ensureIsStaff, + + staff.middleware.ensureProjectsCount, + + staff.middleware.ensureProjects, + staff.middleware.ensureProjectsUsers, staff.projects.index ); diff --git a/views/projects/list-projects.ejs b/views/projects/list-projects.ejs index c78bf9f..c41ae07 100644 --- a/views/projects/list-projects.ejs +++ b/views/projects/list-projects.ejs @@ -1,6 +1,6 @@ [[ if (projects.length) { ]] - +
[[ projects.forEach(function(project, i) { ]] diff --git a/views/staff/_header.ejs b/views/staff/_header.ejs index 9311948..d726b02 100644 --- a/views/staff/_header.ejs +++ b/views/staff/_header.ejs @@ -4,6 +4,7 @@ vvalls | staff [[ include ../partials/meta ]] +
diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs new file mode 100644 index 0000000..ab8c9b3 --- /dev/null +++ b/views/staff/_users.ejs @@ -0,0 +1,15 @@ +
+[[ users.forEach(function(user){ ]] + + + + + +[[ }) ]] +
+ [[- user.username ]] + + [[- user.displayName ]] + + [[- user.last_seen ]] +
diff --git a/views/staff/_users_recent.ejs b/views/staff/_users_recent.ejs new file mode 100644 index 0000000..ff3fd55 --- /dev/null +++ b/views/staff/_users_recent.ejs @@ -0,0 +1,20 @@ + + + + +[[ users.forEach(function(user){ ]] + + + + + +[[ }) ]] +
+ recent users +
+ [[- user.username ]] + + [[- user.displayName ]] + + [[- user.last_seen ]] +
diff --git a/views/staff/index.ejs b/views/staff/index.ejs index fbe67a7..0cb67da 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -1,10 +1,11 @@ [[ include _header ]]

Staff Area

- + +users: [[- userCount ]] +projects: [[- projectCount ]] + +
+[[ include _users_recent ]] [[ include _footer ]] \ No newline at end of file diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs index 62c0ae2..fb072d8 100644 --- a/views/staff/users/index.ejs +++ b/views/staff/users/index.ejs @@ -1,4 +1,6 @@ [[ include ../_header ]]

Users

+[[ include _users ]] + [[ include ../_footer ]] -- cgit v1.2.3-70-g09d2 From b2164f9f6001dcac952a3d2b301f1425fdb3cbe9 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 4 Sep 2014 13:50:40 -0400 Subject: admin users views --- public/assets/stylesheets/app.css | 4 ++- public/assets/stylesheets/staff.css | 38 +++++++++++++++++++- server/lib/api/projects.js | 2 ++ server/lib/util.js | 4 ++- server/lib/views/staff.js | 70 ++++++++++++++++++++++++++----------- views/staff/_footer.ejs | 6 ++++ views/staff/_header.ejs | 3 +- views/staff/_projects.ejs | 22 ++++++++++++ views/staff/_stats.ejs | 13 +++++++ views/staff/index.ejs | 14 +++++--- views/staff/projects/index.ejs | 10 ++++++ views/staff/projects/show.ejs | 15 ++++++++ views/staff/projects/show_404.ejs | 8 +++++ views/staff/users/index.ejs | 10 +++++- views/staff/users/show.ejs | 14 +++++++- views/staff/users/show_404.ejs | 8 +++++ 16 files changed, 210 insertions(+), 31 deletions(-) create mode 100644 views/staff/_projects.ejs create mode 100644 views/staff/_stats.ejs (limited to 'views/staff/index.ejs') diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 25bcf56..17a7dc0 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -164,6 +164,7 @@ h5 { .page.profile { color:white; } +.page table.demo, .page table.profilepage, .page table.projectList { width: 100%; @@ -193,6 +194,7 @@ iframe.embed { z-index: -1; pointer-events: none; } +.page table.demo td, .page table.profilepage td, .page table.projectList td { width: 33.3333%; @@ -241,7 +243,7 @@ iframe.embed { color:white; } -#projectList .editBtn { +.projectList .editBtn { position: absolute; right: 10px; top: 10px; diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index 0208878..2d1f802 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -4,7 +4,43 @@ th, b { font-weight: bold; } -#users td { +table { + display: inline-block; + margin-right: 40px; + vertical-align: top; +} +td, th { text-align: left; padding: 2px 5px; +} +.staff .body { + text-align: left; +} +.staff h1 { + text-align: left; + display: inline-block; +} +.staff nav { + display: inline-block; + text-align: left; +} +.staff nav a { + padding-left: 20px; +} +.staff hr { + border: 1px solid #bbb; + margin: 5px auto 10px; +} +.body { + width: 80%; + margin: 0 auto; +} +.jsonview * { + font-family: monospace !important; +} +.staff { + font-size: 15px; +} +.staff .editLinks a { + color: #00f; } \ No newline at end of file diff --git a/server/lib/api/projects.js b/server/lib/api/projects.js index 2a5beff..da41b48 100644 --- a/server/lib/api/projects.js +++ b/server/lib/api/projects.js @@ -41,6 +41,7 @@ var projects = { data.media = JSON.parse(data.media) data.colors = JSON.parse(data.colors) data.startPosition = JSON.parse(data.startPosition) + data.created_at = new Date () upload.put("projects", req.files.thumbnail, { unacceptable: function(err){ @@ -72,6 +73,7 @@ var projects = { data.name = util.sanitize(data.name) data.slug = util.slugify(data.name) data.description = util.sanitize(data.description) + data.updated_at = new Date () if (req.files.thumbnail) { upload.put("projects", req.files.thumbnail, { diff --git a/server/lib/util.js b/server/lib/util.js index 6d43750..791d3e2 100644 --- a/server/lib/util.js +++ b/server/lib/util.js @@ -8,7 +8,6 @@ var nonAlphanumerics = new RegExp('[^-_a-zA-Z0-9]', 'g') var consecutiveDashes = new RegExp("-+", 'g') var entities = new RegExp("[<>&]", 'g') - var util = {} util.trim = function (s){ return (s || "").replace(whitespaceHead,"").replace(whitespaceTail,"") } @@ -19,6 +18,9 @@ util.slugify = function (s){ util.sanitize = function (s){ return (s || "").replace(entities, "") } +util.escape = function (s){ + return (s || "").replace(/&/g, "&").replace(//g, ">") +} util.capitalize = function (s) { return (s || "").split(" ").map(util.capitalizeWord).join(" "); } diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 9643626..cf43081 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -15,7 +15,7 @@ var staff = module.exports = { fields: { user: "_id username displayName created_at updated_at last_seen created_ip last_ip", - project: "_id name slug created_at updated_at", + project: "_id name slug user_id privacy created_at updated_at", }, defaults: { @@ -35,9 +35,10 @@ var staff = module.exports = { case 'date': sort = {'created_at': -1} break - case 'lastseen': + case 'last_seen': sort = {'last_seen': -1} break + case 'username': default: sort = {'username': 1} break @@ -63,7 +64,7 @@ var staff = module.exports = { var sort switch (req.params.sort) { case 'date': - sort = {'date': -1} + sort = {'created_at': -1} break default: sort = {'slug': 1} @@ -75,13 +76,34 @@ var staff = module.exports = { .skip(offset) .limit(50) .exec(function (err, projects) { - res.locals.projects = projects.map(staff.helpers.projects) + res.locals.projects = projects.map(staff.helpers.project) next() }) }, + + ensureRecentProjects: function(req, res, next){ + var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } } + staff.middleware.ensureProjects(dreq, res, next) + }, ensureProjectsUsers: function(req, res, next){ - + if (! res.locals.projects || ! res.locals.projects.length) { return next() } + var dedupe = {}, user_ids + res.locals.projects.forEach(function(project){ + dedupe[ project.user_id ] = dedupe[ project.user_id ] || [] + dedupe[ project.user_id ].push(project) + }) + user_ids = _.keys(dedupe) + User.find({ _id: user_ids }) + .select(staff.fields.user) + .exec(function (err, users) { + users.forEach(function(user){ + dedupe[user._id].forEach(function(project){ + project.user = user + }) + }) + next() + }) }, ensureProfile: function(req, res, next){ @@ -116,7 +138,7 @@ var staff = module.exports = { next() }) }, - + ensureProfileProjectCount: function(req, res, next){ if (! res.locals.profile) { return next() } Project.count({ user_id: res.locals.profile._id}, function(err, count){ @@ -177,6 +199,8 @@ var staff = module.exports = { project: function(project){ project = project.toObject() + project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY H:MM") + project.user = {} return project } }, @@ -234,23 +258,19 @@ var staff = module.exports = { staff.projects.show ); -// app.post('/staff/bless', -// middleware.ensureAuthenticated, -// views.staff.bless -// ); + + app.put('/staff/users/:username/bless', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.users.bless + ); }, index: function(req, res){ res.render('staff/index') }, - - bless: function(req, res){ - req.user.isStaff = true - req.user.save(function(){ - res.redirect("/staff") - }) - }, - + // /staff/users/ // /staff/users/:username users: { @@ -259,12 +279,20 @@ var staff = module.exports = { }, show: function(req, res){ if (res.locals.profile) { - res.render('staff/users/show') + res.render('staff/users/show', { + profileJSON: util.escape( JSON.stringify( res.locals.profile ) ) + }) } else { res.render('staff/users/show_404') } }, + bless: function(req, res){ + res.locals.profile.isStaff = req.body.isStaff + res.locals.profile.save(function(){ + res.redirect("/staff") + }) + }, }, // /staff/projects/ @@ -275,7 +303,9 @@ var staff = module.exports = { }, show: function(req, res){ if (res.locals.project) { - res.render('staff/projects/show') + res.render('staff/projects/show', { + projectJSON: util.escape( JSON.stringify( res.locals.profile ) ) + }) } else { res.render('staff/projects/show_404') diff --git a/views/staff/_footer.ejs b/views/staff/_footer.ejs index 580828f..c363beb 100644 --- a/views/staff/_footer.ejs +++ b/views/staff/_footer.ejs @@ -1,3 +1,4 @@ + [[ include ../partials/confirm-modal ]] [[ include ../partials/footer ]] @@ -5,4 +6,9 @@ [[ include ../partials/scripts ]] + diff --git a/views/staff/_header.ejs b/views/staff/_header.ejs index d726b02..1880c98 100644 --- a/views/staff/_header.ejs +++ b/views/staff/_header.ejs @@ -7,7 +7,8 @@ -
+
[[ include ../partials/header ]]
+
diff --git a/views/staff/_projects.ejs b/views/staff/_projects.ejs new file mode 100644 index 0000000..83041ae --- /dev/null +++ b/views/staff/_projects.ejs @@ -0,0 +1,22 @@ + +[[ projects.forEach(function(project){ ]] + + + + + + + +[[ }) ]] +
+ [[- project.name ]] + + [[- project.user.username ]] + + [[- project.date ]] + + [[- project.privacy ? "private" : "" ]] +
diff --git a/views/staff/_stats.ejs b/views/staff/_stats.ejs new file mode 100644 index 0000000..6439ab9 --- /dev/null +++ b/views/staff/_stats.ejs @@ -0,0 +1,13 @@ + + + + + + + + + + + + +
stats
users[[- userCount ]]
projects[[- projectCount ]]
diff --git a/views/staff/index.ejs b/views/staff/index.ejs index 0cb67da..842e086 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -2,10 +2,14 @@

Staff Area

-users: [[- userCount ]] -projects: [[- projectCount ]] - -
-[[ include _users_recent ]] + + +
+ + [[ include _users_recent ]] + [[ include _stats ]] [[ include _footer ]] \ No newline at end of file diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs index a27a132..a5a9308 100644 --- a/views/staff/projects/index.ejs +++ b/views/staff/projects/index.ejs @@ -1,4 +1,14 @@ [[ include ../_header ]]

Projects

+ + +
+ +[[ include ../_projects ]] + [[ include ../_footer ]] diff --git a/views/staff/projects/show.ejs b/views/staff/projects/show.ejs index 01b5c76..e821614 100644 --- a/views/staff/projects/show.ejs +++ b/views/staff/projects/show.ejs @@ -1,2 +1,17 @@ [[ include ../_header ]] + +

Project

+ + + +
+ +
+ [[- projectJSON ]] +
+ [[ include ../_footer ]] diff --git a/views/staff/projects/show_404.ejs b/views/staff/projects/show_404.ejs index e0cf0e2..193333f 100644 --- a/views/staff/projects/show_404.ejs +++ b/views/staff/projects/show_404.ejs @@ -1,4 +1,12 @@ [[ include ../_header ]]

Project not found

+ + +
+ [[ include ../_footer ]] diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs index fb072d8..ad92fc3 100644 --- a/views/staff/users/index.ejs +++ b/views/staff/users/index.ejs @@ -1,6 +1,14 @@ [[ include ../_header ]]

Users

-[[ include _users ]] + + +
+ +[[ include ../_users ]] [[ include ../_footer ]] diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs index b5e1a6c..d306443 100644 --- a/views/staff/users/show.ejs +++ b/views/staff/users/show.ejs @@ -1,4 +1,16 @@ [[ include ../_header ]] -

User: [[ profile.username ]]

+

User: [[- profile.username ]]

+ + + +
+ +
+ [[- profileJSON ]] +
[[ include ../_footer ]] diff --git a/views/staff/users/show_404.ejs b/views/staff/users/show_404.ejs index c52e1e7..3fd20a8 100644 --- a/views/staff/users/show_404.ejs +++ b/views/staff/users/show_404.ejs @@ -1,4 +1,12 @@ [[ include ../_header ]]

User not found

+ + +
+ [[ include ../_footer ]] -- cgit v1.2.3-70-g09d2 From 415dad29407362a76fde6d07d8b100285a84518d Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 4 Sep 2014 17:52:48 -0400 Subject: media api --- public/assets/img/profile.png | Bin 0 -> 9320 bytes public/assets/javascripts/ui/site/StaffView.js | 33 +++--- public/assets/stylesheets/staff.css | 4 + server/lib/views/staff.js | 141 ++++++++++++++++++++++--- views/staff/_media.ejs | 1 + views/staff/_stats.ejs | 4 + views/staff/_users.ejs | 2 +- views/staff/_users_recent.ejs | 6 +- views/staff/index.ejs | 1 + views/staff/media/index.ejs | 16 +++ views/staff/media/show.ejs | 14 +++ views/staff/media/show_404.ejs | 14 +++ views/staff/projects/index.ejs | 2 + views/staff/projects/show.ejs | 1 + views/staff/projects/show_404.ejs | 2 + views/staff/users/index.ejs | 2 + views/staff/users/show.ejs | 26 +++-- views/staff/users/show_404.ejs | 1 + 18 files changed, 230 insertions(+), 40 deletions(-) create mode 100644 public/assets/img/profile.png create mode 100644 views/staff/_media.ejs create mode 100644 views/staff/media/index.ejs create mode 100644 views/staff/media/show.ejs create mode 100644 views/staff/media/show_404.ejs (limited to 'views/staff/index.ejs') diff --git a/public/assets/img/profile.png b/public/assets/img/profile.png new file mode 100644 index 0000000..bde68e0 Binary files /dev/null and b/public/assets/img/profile.png differ diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js index 8f677cb..fd173e5 100644 --- a/public/assets/javascripts/ui/site/StaffView.js +++ b/public/assets/javascripts/ui/site/StaffView.js @@ -7,7 +7,7 @@ var StaffView = View.extend({ initialize: function() { this.$toggleStaff = $("#toggle-staff") - if (this.$toggleStaff.data().isstaff) { + if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) { this.$toggleStaff.html("Is Staff") } }, @@ -22,20 +22,23 @@ var StaffView = View.extend({ toggleStaff: function(){ var state = ! this.$toggleStaff.data().isstaff - $.ajax({ - type: "put", - dataType: "json", - url: window.location.href + "/bless", - data: { - state: state, - _csrf: $("#_csrf").val(), - }, - success: function(data){ - this.$toggleStaff.data("isstaff", data.state) - this.$toggleStaff.html(data.state ? "Is Staff" : "Make Staff") - $("#is-staff").html(data.state ? "yes" : "no") - }.bind(this) - }) + var verb = state ? "promote this user to staff?" : "remove this user from staff?" + ConfirmModal.confirm("Are you sure you want to " + verb, function(){ + $.ajax({ + type: "put", + dataType: "json", + url: window.location.href + "/bless", + data: { + state: state, + _csrf: $("#_csrf").val(), + }, + success: function(data){ + this.$toggleStaff.data("isstaff", data.state) + this.$toggleStaff.html(data.state ? "Is Staff" : "Make Staff") + $("#is-staff").html(data.state ? "yes" : "no") + }.bind(this) + }) + }.bind(this)) }, }) diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index 9b9226f..02510a3 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -78,6 +78,10 @@ h2 { display: inline-block; background-size: cover; } +#actions button { + float: none; + width: auto; +} iframe.embed { position: static; width: 100%; diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index b78fd5a..b9fe78a 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -28,10 +28,10 @@ var staff = module.exports = { middleware: { ensureUsers: function(req, res, next){ - var limit = Math.max( Number(req.params.limit) || 50, 200 ) - var offset = Number(req.params.offset) || 0 + var limit = Math.max( Number(req.query.limit) || 50, 200 ) + var offset = Number(req.query.offset) || 0 var sort - switch (req.params.sort) { + switch (req.query.sort) { case 'date': sort = {'created_at': -1} break @@ -60,9 +60,10 @@ var staff = module.exports = { }, ensureProjects: function(req, res, next){ - var offset = Number(req.params.offset) || 0 + var limit = Math.max( Number(req.query.limit) || 50, 200 ) + var offset = Number(req.query.offset) || 0 var sort - switch (req.params.sort) { + switch (req.query.sort) { case 'date': sort = {'created_at': -1} break @@ -74,13 +75,34 @@ var staff = module.exports = { .select(staff.fields.project) .sort(sort) .skip(offset) - .limit(50) + .limit(limit) .exec(function (err, projects) { res.locals.projects = projects.map(staff.helpers.project) next() }) }, + ensureMedia: function(req, res, next){ + var limit = Math.max( Number(req.query.limit) || 50, 200 ) + var offset = Number(req.query.offset) || 0 + var sort + switch (req.query.sort) { + default: + case 'date': + sort = {'created_at': -1} + break + } + Media.find({}) + // .select(staff.fields.media) + .sort(sort) + .skip(offset) + .limit(limit) + .exec(function (err, media) { + res.locals.media = media.map(staff.helpers.media) + next() + }) + }, + ensureRecentProjects: function(req, res, next){ var dreq = { params: { sort: 'created_at', limit: 20, offset: 0 } } staff.middleware.ensureProjects(dreq, res, next) @@ -88,18 +110,32 @@ var staff = module.exports = { ensureProjectsUsers: function(req, res, next){ if (! res.locals.projects || ! res.locals.projects.length) { return next() } + staff.middleware.ensureObjectsUsers(res.locals.projects, next) + }, + + ensureMediaUsers: function(req, res, next){ + if (! res.locals.media || ! res.locals.media.length) { return next() } + staff.middleware.ensureObjectsUsers(res.locals.media, next) + }, + + ensureMediaUser: function(req, res, next){ + if (! res.locals.media) { return next() } + staff.middleware.ensureObjectsUsers([ res.locals.media ], next) + }, + + ensureObjectsUsers: function(objects, next){ var dedupe = {}, user_ids - res.locals.projects.forEach(function(project){ - dedupe[ project.user_id ] = dedupe[ project.user_id ] || [] - dedupe[ project.user_id ].push(project) + objects.forEach(function(obj){ + dedupe[ obj.user_id ] = dedupe[ obj.user_id ] || [] + dedupe[ obj.user_id ].push(obj) }) user_ids = _.keys(dedupe) User.find({ _id: user_ids }) .select(staff.fields.user) .exec(function (err, users) { users.forEach(function(user){ - dedupe[user._id].forEach(function(project){ - project.user = user + dedupe[user._id].forEach(function(obj){ + obj.user = user }) }) next() @@ -125,6 +161,25 @@ var staff = module.exports = { } }, + ensureSingleMedia: function(req, res, next){ + var id = req.params.id + if (id) { + Media.findOne({ _id: id }, function (err, id) { + if (media) { + res.locals.media = req.method == "GET" ? staff.helpers.media(media) : media + } + else { + res.locals.media = null + } + next() + }) + } + else { + res.locals.media = null + next() + } + }, + ensureUsersCount: function(req, res, next){ User.count({}, function(err, count){ res.locals.userCount = count || 0 @@ -138,6 +193,13 @@ var staff = module.exports = { next() }) }, + + ensureMediaCount: function(req, res, next){ + Media.count({}, function(err, count){ + res.locals.mediaCount = count || 0 + next() + }) + }, ensureProfileProjectCount: function(req, res, next){ if (! res.locals.profile) { return next() } @@ -202,7 +264,14 @@ var staff = module.exports = { project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY H:MM") project.user = {} return project - } + }, + + media: function(media){ + media = media.toObject() + media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY H:MM") + media.user = {} + return media + } }, route: function(app){ @@ -213,9 +282,14 @@ var staff = module.exports = { staff.middleware.ensureRecentUsers, staff.middleware.ensureUsersCount, staff.middleware.ensureProjectsCount, + staff.middleware.ensureMediaCount, staff.index ); + + // + // users + app.get('/staff/users', middleware.ensureAuthenticated, middleware.ensureIsStaff, @@ -244,6 +318,10 @@ var staff = module.exports = { staff.users.bless ); + + // + // projects + app.get('/staff/projects', middleware.ensureAuthenticated, middleware.ensureIsStaff, @@ -266,6 +344,28 @@ var staff = module.exports = { staff.projects.show ); + + // + // media + + app.get('/staff/media', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureMedia, + staff.middleware.ensureMediaUsers, + + staff.media.index + ); + app.get('/staff/media/:id', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureSingleMedia, + staff.middleware.ensureMediaUser, + + staff.media.show + ); }, @@ -316,5 +416,22 @@ var staff = module.exports = { } }, }, + + media: { + index: function(req, res){ + res.render('staff/media/index') + }, + show: function(req, res){ + if (res.locals.project) { + res.render('staff/media/show', { + mediaJSON: util.escape( JSON.stringify( res.locals.media ) ), + mediaUserJSON: util.escape( JSON.stringify( res.locals.mediaUser ) ), + }) + } + else { + res.render('staff/media/show_404') + } + }, + } } \ No newline at end of file diff --git a/views/staff/_media.ejs b/views/staff/_media.ejs new file mode 100644 index 0000000..27949aa --- /dev/null +++ b/views/staff/_media.ejs @@ -0,0 +1 @@ +media \ No newline at end of file diff --git a/views/staff/_stats.ejs b/views/staff/_stats.ejs index 6439ab9..d1ad96f 100644 --- a/views/staff/_stats.ejs +++ b/views/staff/_stats.ejs @@ -10,4 +10,8 @@ projects [[- projectCount ]] + + media + [[- mediaCount ]] + diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs index 344ee0c..d46058f 100644 --- a/views/staff/_users.ejs +++ b/views/staff/_users.ejs @@ -11,7 +11,7 @@ [[- user.displayName ]] - [view profile] + [view profile] [[- user.last_seen ]] diff --git a/views/staff/_users_recent.ejs b/views/staff/_users_recent.ejs index e55fe28..b452c08 100644 --- a/views/staff/_users_recent.ejs +++ b/views/staff/_users_recent.ejs @@ -7,15 +7,13 @@ [[ users.forEach(function(user){ ]] - [[ if (user.photo) { ]] -
- [[ } ]] +
[[- user.username ]] - [view profile] + [view profile] [[- user.displayName ]] diff --git a/views/staff/index.ejs b/views/staff/index.ejs index 842e086..f721339 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -5,6 +5,7 @@
diff --git a/views/staff/media/index.ejs b/views/staff/media/index.ejs new file mode 100644 index 0000000..76aaafb --- /dev/null +++ b/views/staff/media/index.ejs @@ -0,0 +1,16 @@ +[[ include ../_header ]] + +

Media

+ + + +
+ +[[ include ../_media ]] + +[[ include ../_footer ]] diff --git a/views/staff/media/show.ejs b/views/staff/media/show.ejs new file mode 100644 index 0000000..43afe14 --- /dev/null +++ b/views/staff/media/show.ejs @@ -0,0 +1,14 @@ +[[ include ../_header ]] + +

Media [[- media.type ]]

+ + + +
+ +[[ include ../_footer ]] diff --git a/views/staff/media/show_404.ejs b/views/staff/media/show_404.ejs new file mode 100644 index 0000000..f07cef2 --- /dev/null +++ b/views/staff/media/show_404.ejs @@ -0,0 +1,14 @@ +[[ include ../_header ]] + +

Media not found

+ + + +
+ +[[ include ../_footer ]] diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs index a5a9308..a6fad6b 100644 --- a/views/staff/projects/index.ejs +++ b/views/staff/projects/index.ejs @@ -1,10 +1,12 @@ [[ include ../_header ]] +

Projects


diff --git a/views/staff/projects/show.ejs b/views/staff/projects/show.ejs index 23e96b2..0fdb00b 100644 --- a/views/staff/projects/show.ejs +++ b/views/staff/projects/show.ejs @@ -6,6 +6,7 @@ home users projects + media
diff --git a/views/staff/projects/show_404.ejs b/views/staff/projects/show_404.ejs index 193333f..70320c0 100644 --- a/views/staff/projects/show_404.ejs +++ b/views/staff/projects/show_404.ejs @@ -1,10 +1,12 @@ [[ include ../_header ]] +

Project not found


diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs index ad92fc3..8c56565 100644 --- a/views/staff/users/index.ejs +++ b/views/staff/users/index.ejs @@ -1,10 +1,12 @@ [[ include ../_header ]] +

Users


diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs index 2315043..afcd761 100644 --- a/views/staff/users/show.ejs +++ b/views/staff/users/show.ejs @@ -5,6 +5,7 @@ home users projects + media
@@ -21,7 +22,7 @@ [[- profile.displayName ]] - [view profile] + [view profile] @@ -43,6 +44,22 @@ [[- profile.last_seen ]] + + + projects + + + [[- profile.projectCount ]] + + + + + media + + + [[- profile.mediaCount ]] + + ip addresses @@ -77,10 +94,3 @@
[[ include ../_footer ]] - \ No newline at end of file diff --git a/views/staff/users/show_404.ejs b/views/staff/users/show_404.ejs index 3fd20a8..bcd0271 100644 --- a/views/staff/users/show_404.ejs +++ b/views/staff/users/show_404.ejs @@ -5,6 +5,7 @@ home users projects + media
-- cgit v1.2.3-70-g09d2 From 1082e3be99669671b6c745307131a7cb8d54eabc Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 5 Sep 2014 15:54:12 -0400 Subject: pagination on all queries --- public/assets/stylesheets/staff.css | 6 +++ server/lib/views/staff.js | 75 ++++++++++++++++++++++++++++++------- views/staff/_pagination.ejs | 17 +++++++++ views/staff/index.ejs | 2 +- views/staff/media/index.ejs | 2 + views/staff/projects/index.ejs | 2 + views/staff/users/index.ejs | 2 + views/staff/users/media.ejs | 2 + views/staff/users/show.ejs | 17 ++++----- 9 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 views/staff/_pagination.ejs (limited to 'views/staff/index.ejs') diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index 05d3541..aa21f9b 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -95,3 +95,9 @@ iframe.embed { .page table.projectList td.border { border: 0; } +#pagination { + margin: 10px 0; +} +#pagination a { + color: #00f; +} \ No newline at end of file diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index e776b7f..2ffea0d 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -27,10 +27,14 @@ var staff = module.exports = { middleware: { - ensureUsers: function(req, res, next, criteria){ - var limit = Math.max( Number(req.query.limit) || 50, 200 ) - var offset = Number(req.query.offset) || 0 + ensureUsers: function(req, res, next){ + var paginationInfo = res.locals.pagination = {} + var criteria = req.criteria || {} + var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 ) + var offset = paginationInfo.offset = Number(req.query.offset) || 0 var sort + paginationInfo.sort = req.query.sort + paginationInfo.sortOptions = ["date", "last_seen", "username"] switch (req.query.sort) { case 'date': sort = {'created_at': -1} @@ -41,9 +45,9 @@ var staff = module.exports = { case 'username': default: sort = {'username': 1} + paginationInfo.sort = "username" break } - criteria = criteria || {} User.find(criteria) .select(staff.fields.user) .sort(sort) @@ -60,19 +64,24 @@ var staff = module.exports = { staff.middleware.ensureUsers(dreq, res, next) }, - ensureProjects: function(req, res, next, criteria){ - var limit = Math.max( Number(req.query.limit) || 50, 200 ) - var offset = Number(req.query.offset) || 0 + ensureProjects: function(req, res, next){ + var paginationInfo = res.locals.pagination = {} + var criteria = req.criteria || {} + var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 ) + var offset = paginationInfo.offset = Number(req.query.offset) || 0 var sort + paginationInfo.sort = req.query.sort + paginationInfo.sortOptions = ["date", "name"] switch (req.query.sort) { case 'date': sort = {'created_at': -1} break + case 'name': default: + paginationInfo.sort = "name" sort = {'slug': 1} break } - criteria = criteria || {} Project.find(criteria) .select(staff.fields.project) .sort(sort) @@ -84,17 +93,21 @@ var staff = module.exports = { }) }, - ensureMedia: function(req, res, next, criteria){ - var limit = Math.max( Number(req.query.limit) || 50, 200 ) - var offset = Number(req.query.offset) || 0 + ensureMedia: function(req, res, next){ + var paginationInfo = res.locals.pagination = {} + var criteria = req.criteria || {} + var limit = paginationInfo.limit = Math.min( Number(req.query.limit) || 50, 200 ) + var offset = paginationInfo.offset = Number(req.query.offset) || 0 var sort + paginationInfo.sort = req.query.sort + paginationInfo.sortOptions = ["date"] switch (req.query.sort) { default: case 'date': + paginationInfo.sort = "date" sort = {'created_at': -1} break } - criteria = criteria || {} Media.find(criteria) // .select(staff.fields.media) .sort(sort) @@ -233,7 +246,8 @@ var staff = module.exports = { ensureProfileMedia: function(req, res, next){ if (! res.locals.profile) { return next() } - staff.middleware.ensureMedia(req, res, next, { user_id: res.locals.profile._id }) + req.criteria = { user_id: res.locals.profile._id } + staff.middleware.ensureMedia(req, res, next) }, ensureProject: function(req, res, next){ @@ -328,6 +342,7 @@ var staff = module.exports = { staff.middleware.ensureProfile, staff.middleware.ensureProfileMedia, + staff.middleware.ensureProfileMediaCount, staff.users.media ); @@ -373,6 +388,8 @@ var staff = module.exports = { middleware.ensureAuthenticated, middleware.ensureIsStaff, + staff.middleware.ensureMediaCount, + staff.middleware.ensureMedia, staff.middleware.ensureMediaUsers, @@ -388,6 +405,26 @@ var staff = module.exports = { staff.media.show ); + }, + + paginate: function(req, res){ + var info = res.locals.pagination + info.query = "sort=" + info.sort + "&limit=" + info.limit + info.first_page = 0 + info.last_page = Math.max(0, info.max - info.limit) + info.sortOptions = info.sortOptions + if (info.offset > 0) { + info.prev_page = Math.max(0, info.offset - info.limit) + } + else { + info.prev_page = -1 + } + if (info.count == info.limit && info.offset + info.limit < info.max) { + info.next_page = info.offset + info.limit + } + else { + info.next_page = -1 + } }, index: function(req, res){ @@ -398,6 +435,9 @@ var staff = module.exports = { // /staff/users/:username users: { index: function(req, res){ + res.locals.pagination.count = res.locals.users.length + res.locals.pagination.max = res.locals.userCount + staff.paginate(req, res) res.render('staff/users/index') }, show: function(req, res){ @@ -412,6 +452,9 @@ var staff = module.exports = { }, media: function(req, res){ if (res.locals.profile) { + res.locals.pagination.count = res.locals.media.length + res.locals.pagination.max = res.locals.profile.mediaCount + staff.paginate(req, res) res.render('staff/users/media') } else { @@ -430,6 +473,9 @@ var staff = module.exports = { // /staff/projects/:name projects: { index: function(req, res){ + res.locals.pagination.count = res.locals.projects.length + res.locals.pagination.max = res.locals.projectCount + staff.paginate(req, res) res.render('staff/projects/index') }, show: function(req, res){ @@ -448,6 +494,9 @@ var staff = module.exports = { media: { index: function(req, res){ + res.locals.pagination.count = res.locals.media.length + res.locals.pagination.max = res.locals.mediaCount + staff.paginate(req, res) res.render('staff/media/index') }, show: function(req, res){ diff --git a/views/staff/_pagination.ejs b/views/staff/_pagination.ejs new file mode 100644 index 0000000..6c3bfb1 --- /dev/null +++ b/views/staff/_pagination.ejs @@ -0,0 +1,17 @@ +[[ if (pagination.prev_page !== -1 && pagination.next_page !== -1) { ]] + +[[ } ]] \ No newline at end of file diff --git a/views/staff/index.ejs b/views/staff/index.ejs index f721339..5ca7269 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -9,7 +9,7 @@
- + [[ include _users_recent ]] [[ include _stats ]] diff --git a/views/staff/media/index.ejs b/views/staff/media/index.ejs index 76aaafb..516af2d 100644 --- a/views/staff/media/index.ejs +++ b/views/staff/media/index.ejs @@ -11,6 +11,8 @@
+[[ include ../_pagination ]] [[ include ../_media ]] +[[ include ../_pagination ]] [[ include ../_footer ]] diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs index a6fad6b..482ea25 100644 --- a/views/staff/projects/index.ejs +++ b/views/staff/projects/index.ejs @@ -11,6 +11,8 @@
+[[ include ../_pagination ]] [[ include ../_projects ]] +[[ include ../_pagination ]] [[ include ../_footer ]] diff --git a/views/staff/users/index.ejs b/views/staff/users/index.ejs index 8c56565..f14d666 100644 --- a/views/staff/users/index.ejs +++ b/views/staff/users/index.ejs @@ -11,6 +11,8 @@
+[[ include ../_pagination ]] [[ include ../_users ]] +[[ include ../_pagination ]] [[ include ../_footer ]] diff --git a/views/staff/users/media.ejs b/views/staff/users/media.ejs index 6ea2668..b13e5fb 100644 --- a/views/staff/users/media.ejs +++ b/views/staff/users/media.ejs @@ -11,6 +11,8 @@
+[[ include ../_pagination ]] [[ include ../_media ]] +[[ include ../_pagination ]] [[ include ../_footer ]] diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs index 127ca8c..8e9b447 100644 --- a/views/staff/users/show.ejs +++ b/views/staff/users/show.ejs @@ -80,17 +80,14 @@ [[- profile.isStaff ? "yes" : "no" ]] - - - - - - [[ if (String(user._id) != String(profile._id)) { ]] - - [[ } ]] - - + +

+
+ [[ if (String(user._id) != String(profile._id)) { ]] + + [[ } ]] +

Projects

-- cgit v1.2.3-70-g09d2