From 190a145cf1433fde570df1ac9784d4c5cea77d3d Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 7 Jan 2015 18:28:46 -0500 Subject: everything but saving --- server/lib/middleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/lib/middleware.js') diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 4848ab0..797d677 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -75,7 +75,7 @@ var middleware = { } next() }) - } + } else { req.project = null next() -- cgit v1.2.3-70-g09d2 From 5adac681bdb43b8b709795fa501689fb9ae8a4e1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 28 Jan 2015 19:18:27 -0500 Subject: many methods --- package.json | 1 + server/lib/api/subscription.js | 124 ++++++++++++++++++++++++++++++++---- server/lib/middleware.js | 2 +- server/lib/schemas/Subscription.js | 6 +- server/lib/views/staff.js | 2 +- server/lib/webhook/webhook.js | 2 +- views/about/brochure.ejs | 15 +++-- views/partials/header.ejs | 1 + views/staff/_users.ejs | 1 + views/staff/plans/_form.ejs | 5 ++ views/staff/subscriptions/index.ejs | 2 +- views/staff/users/show.ejs | 1 + 12 files changed, 135 insertions(+), 27 deletions(-) (limited to 'server/lib/middleware.js') diff --git a/package.json b/package.json index 8afb96e..e89fcd9 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "express-subdomains": "0.0.5", "html-entities": "~1.0.10", "intro.js": "^0.9.0", + "js2xml": "^1.0.0", "knox": "~0.8.10", "lodash": "~2.4.1", "marked": "~0.3.2", diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 83644cf..40aa715 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -9,7 +9,22 @@ var _ = require('lodash'), Layout = require('../schemas/Layout'), Subscription = require('../schemas/Subscription'); +var plan_levels = { + free: 0, + basic: 1, + pro: 2, +} + var subscription = module.exports = { + middleware: { + ensureSubscription: function(req, res, next){ + Subscription.findOne({ user_id: req.user._id }, function(err, data){ + if (err) { return next() } + req.subscription = data + next() + }) + }, + } /* index: function(req, res){ @@ -18,30 +33,115 @@ var subscription = module.exports = { }) }, */ - middleware: { - fetchAccount: function(req, res, next){ - recurly.subscriptions.listByAccount(req.user._id, function(data){ - }) - }, - }, // synchronise an account with recurly.. - // useful when testing locally (if webhooks do not fire) + // useful when testing locally (where webhooks cannot be received) sync: function(req, res){ - // fetch req.user._id + var subscriber = req.subscription || new Subscription () + var user = req.user + recurly.subscriptions.listByAccount(req.user._id, function(data){ + if (data.description !== 200) { + res.json({ error: "no account" }) + return + } + if (! data.subscriptions.subscription) { + res.json({ error: "account error" }) + return + } + + var plan = data.subscriptions.subscription.plan.plan_code.split("-") + var plan_type = plan[0] + var plan_period = plan[1] + + user.plan_type = plan_type + user.plan_level = plan_levels[plan_type] + + subscriber.uuid = data.subscriptions.subscription.uuid + subscriber.user_id = user._id + subscriber.plan_type = plan_type + subscriber.plan_period = plan_period + subscriber.plan_level = plan_levels[plan_type] + + var add_ons = data.subscriptions.subscription.subscription_add_ons.subscription_add_on + if (add_ons) { + if (add_ons.add_on_code) { + add_ons = [ add_ons ] + } + // TODO: handle multiple add-ons.. presumably this will work + add_ons.forEach(function(add_on){ + var add_on_type = add_on.add_on_code.split("-")[1] + if (add_on_type == "basic") { + subscriber.basic_layouts = parseInt( add_on.quantity._ ) + } + if (add_on_type == "pro") { + subscriber.pro_layouts = parseInt( add_on.quantity._ ) + } + }) + } + else { + subscriber.basic_layouts = 0 + subscriber.pro_layouts = 0 + } + + subscriber.save(function(){ + user.save(function(){ + res.render(subscriber) + }) + }) + }) }, show: function(req, res){ - // fetch from recurly + res.json(req.subscription || { error: "no subscription" }) }, update: function(req, res){ - // update plan_type on recurly - // update add_ons on recurly + if (! req.subscription ) { + return res.json({ error: "no subscription" }) + } + if (! (req.body.plan_type in plan_levels)) { + return res.json({ error: "bad input" }) + } + var subscriber = req.subscription + + // change.. + // data.plan_code + // data.subscription_add_ons = [] + // add_on.add_on_code + // add_on.quantity + var basic_layouts = max(0, parseInt(req.body.basic_layouts)) + var pro_layouts = max(0, parseInt(req.body.pro_layouts)) + + var data = {} + data.plan_code = req.body.plan_type + "_monthly" + data.subscription_add_ons = [] + + if (plan_levels[req.body.plan_type]) { + data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts }) + } + + if (req.body.plan_type == "pro") { + data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts }) + } + + + recurly.subscriptions.update(subscriber.uuid, data, function(){ + return res.json(subscriber) + }) }, destroy: function(req, res){ - // destroy on recurly + if (! req.subscription ) { + return res.json({ error: "no subscription" }) + } + var subscriber = req.subscription + + recurly.subscriptions.cancel(subscriber.uuid, function(){ + subscriber.remove(function(){ + req.user.plan_code = 0 + req.user.plan_type = "free" + }) + }) }, }; \ No newline at end of file diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 797d677..7dfe821 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -59,7 +59,7 @@ var middleware = { res.locals.opt = {} next() }, - + ensureProject: function (req, res, next) { if (req.params.slug) { Project.findOne({ slug: req.params.slug }, function(err, project){ diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index b766555..24c5096 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -13,10 +13,8 @@ var SubscriptionSchema = new mongoose.Schema({ plan_period: { type: String, default: "monthly" }, subscription_uuid: { type: String }, - subscription_add_ons: [{ - name: { type: String }, - quantity: { type: Number }, - }], + basic_layouts: { type: Number, default: 0 }, + pro_layouts: { type: Number, default: 0 }, history: [{ action: { type: String }, diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 74dd7cd..67193fe 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -154,7 +154,7 @@ var staff = module.exports = { }, ensurePlans: function(req, res, next){ - Plan.find(function (err, plans) { + Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) { res.locals.plans = (plans || []).map(staff.helpers.plan) res.locals.plans.sort(function(a,b){ return a.monthly_price }) next() diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js index 4f23d0b..a871a3a 100644 --- a/server/lib/webhook/webhook.js +++ b/server/lib/webhook/webhook.js @@ -149,6 +149,6 @@ var subscribe = module.exports = { route: function(app){ app.post('/subscribe/webhook', subscribe.handle); - app.get('/subscribe/list/:id', subscribe.list); + app.get('/subscribe/list/:id', subscribe.middleware.ensureSubscription, subscribe.list); }, } diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs index 49b03db..1dad763 100644 --- a/views/about/brochure.ejs +++ b/views/about/brochure.ejs @@ -34,12 +34,11 @@
  • VValls logo appears when embedding an exhibition on a web page
  • [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level || user.plan_level < plan.level) { ]] - + + [[ } else if (! user.plan_level) { ]] + [[ } else if (user.plan_level == plan.level) { ]] Current Level - [[ } else { ]] [[ } ]] @@ -56,11 +55,13 @@
  • No VValls logo on embed
  • [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level || user.plan_level < plan.level) { ]] - + + [[ } else if (! user.plan_level) { ]] + [[ } else if (user.plan_level == plan.level) { ]] Current Level + [[ } else if (user.plan_level < plan.level) { ]] + [[ } ]] diff --git a/views/partials/header.ejs b/views/partials/header.ejs index ce5bab9..2acf2bc 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -64,6 +64,7 @@ [[ if (profile && String(user._id) == String(profile._id)) { ]] Settings + Subscription [[ } else if (! profile) { ]] Profile [[ } ]] diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs index d46058f..053e289 100644 --- a/views/staff/_users.ejs +++ b/views/staff/_users.ejs @@ -12,6 +12,7 @@ [view profile] + [recurly] [[- user.last_seen ]] diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs index ae5ca5a..b55c5cd 100644 --- a/views/staff/plans/_form.ejs +++ b/views/staff/plans/_form.ejs @@ -16,6 +16,11 @@
  • +
  • + +
    +
  • +
  • diff --git a/views/staff/subscriptions/index.ejs b/views/staff/subscriptions/index.ejs index d1c0588..3efffb5 100644 --- a/views/staff/subscriptions/index.ejs +++ b/views/staff/subscriptions/index.ejs @@ -1,6 +1,6 @@ [[ include ../_header ]] -

    Users

    +

    Subscriptions

    [[ include ../_nav ]] diff --git a/views/staff/users/show.ejs b/views/staff/users/show.ejs index 4ce1d9a..d6a21d5 100644 --- a/views/staff/users/show.ejs +++ b/views/staff/users/show.ejs @@ -19,6 +19,7 @@ [view profile] [view media] + [view on recurly] -- cgit v1.2.3-70-g09d2 From f84ea4bf323f99479298f0576006267bf4182632 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 6 Aug 2015 17:50:55 -0400 Subject: pass thru plans --- public/assets/stylesheets/staff.css | 2 +- server/index.js | 2 ++ server/lib/middleware.js | 14 ++++++++++++-- server/lib/views/staff.js | 9 ++++++++- 4 files changed, 23 insertions(+), 4 deletions(-) (limited to 'server/lib/middleware.js') diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index ebc240a..7ae4a1e 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -45,7 +45,7 @@ nav.subnav { margin: 20px 5px 200px 5px; padding: 10px; width: 400px; - display: inline-block; + display: block; } hr { border: 1px solid #bbb; diff --git a/server/index.js b/server/index.js index 4926a94..30cf69a 100644 --- a/server/index.js +++ b/server/index.js @@ -82,6 +82,8 @@ site.setup = function(){ // var io = websocket.listen(server) // auth.initSockets(io, SessionStore) + + middleware.updatePlans() } site.route = function () { diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 7dfe821..35c520c 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -6,11 +6,14 @@ var passport = require('passport'), config = require('../../config.json'), User = require('./schemas/User'), Collaborator = require('./schemas/Collaborator'), - Project = require('./schemas/Project'); + Project = require('./schemas/Project'), + Plan = require('./schemas/Plan'); var middleware = { + plans: [], + enableCORS: function (req, res, next) { res.header('Access-Control-Allow-Credentials', true); // TODO Check https vs. http @@ -46,7 +49,7 @@ var middleware = { }, ensureLocals: function (req, res, next) { - res.locals.token = req.csrfToken(); + res.locals.token = req.csrfToken() res.locals.logged_in = req.isAuthenticated() res.locals.user = req.user || { _id: undefined } res.locals.config = config @@ -56,6 +59,7 @@ var middleware = { res.locals.ogUrl = "http://vvalls.com/" res.locals.ogDescription = "3D gallery space, fully customizable" res.locals.ogAuthor = "VValls" + res.locals.plans = plans res.locals.opt = {} next() }, @@ -106,6 +110,12 @@ var middleware = { }) } }, + + updatePlans: function(){ + Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) { + middleware.plans = plans.map(function(plan){ return plan.toObject() }) + }) + }, } diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 07050f1..19b361d 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -56,7 +56,12 @@ var staff = module.exports = { break } if (initial) { - criteria.username = new RegExp('^' + initial, "i") + if (initial == "?") { + criteria.username = new RegExp('^[$a-zA-Z]', "i") + } + else { + criteria.username = new RegExp('^' + initial, "i") + } } User.find(criteria) .select(staff.fields.user) @@ -749,6 +754,7 @@ var staff = module.exports = { new Plan (data).save(function(err, doc){ if (err || ! doc) { return res.json({ error: err }) } + middleware.updatePlans() res.redirect("/staff/plans/") }) }, @@ -767,6 +773,7 @@ var staff = module.exports = { req.plan.save(function(err, doc){ if (err || ! doc) { return res.json({ error: err }) } + middleware.updatePlans() res.redirect("/staff/plans/") }) }, -- cgit v1.2.3-70-g09d2 From 15692020fbc7bdfa66f9ecae0eaf844054c59e4a Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 6 Aug 2015 19:11:23 -0400 Subject: plan restriction business logic --- public/assets/javascripts/ui/site/LayoutsModal.js | 14 ++++++++++++-- server/index.js | 2 +- server/lib/api/layouts.js | 11 ++++++++++- server/lib/middleware.js | 16 +++++++++++++++- 4 files changed, 38 insertions(+), 5 deletions(-) (limited to 'server/lib/middleware.js') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 5974fc3..639d55c 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -15,13 +15,23 @@ var LayoutsIndex = View.extend({ }, populate: function(data){ - if (! data.length) { +/* + if (data.layoutCount > data.plan.basic_layout_limit) { + } + if (data.projectCount > data.plan.stock_project_limit) { + } + if (data.projectCount > data.plan.basic_project_limit) { + } + if (data.projectCount > data.plan.pro_project_limit) { + } +*/ + if (! data.layouts.length) { this.$templates.hide() this.$form.hide() this.$noTemplates.show() } this.$templatesList.empty() - data.forEach(function(room){ + data.layouts.forEach(function(room){ var $span = $("") $span.data("slug", room.slug) diff --git a/server/index.js b/server/index.js index 30cf69a..db9b051 100644 --- a/server/index.js +++ b/server/index.js @@ -139,7 +139,7 @@ site.route = function () { app.get('/project/:slug/view', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader) app.get('/project/:slug/edit', middleware.ensureProject, middleware.ensureIsCollaborator, views.editor) - app.get('/api/layout', middleware.ensureAuthenticated, api.layouts.index) + app.get('/api/layout', middleware.ensureAuthenticated, middleware.ensureUserProjectsCount, middleware.ensureUserLayoutsCount, api.layouts.index) app.get('/api/layout/:slug', middleware.ensureAuthenticated, api.layouts.show) app.post('/api/layout/new', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.create) app.post('/api/layout/edit', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.update) diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index 641e9e2..7e7976c 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -3,13 +3,22 @@ var _ = require('lodash'), util = require('../util'), upload = require('../upload'), + middleware = require('../middleware'), config = require('../../../config.json'), Layout = require('../schemas/Layout'); var layouts = { index: function(req, res){ + // free layouts + // user layouts Layout.find({}, function(err, docs){ - res.json(docs) + res.json({ + layouts: docs, + plan: middleware.plans[ res.locals.user.plan_level || 0 ], + user: res.locals.user, + layoutCount: res.locals.layoutCount, + projectCount: res.locals.projectCount, + }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 35c520c..9d09a10 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -7,6 +7,7 @@ var passport = require('passport'), User = require('./schemas/User'), Collaborator = require('./schemas/Collaborator'), Project = require('./schemas/Project'), + Layout = require('./schemas/Layout'), Plan = require('./schemas/Plan'); @@ -63,7 +64,20 @@ var middleware = { res.locals.opt = {} next() }, - + + ensureUserProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id }, function(err, count){ + res.locals.projectCount = count || 0 + next() + }) + }, + ensureUserLayoutsCount: function(req, res, next){ + Layout.count({ user_id: req.user.id }, function(err, count){ + res.locals.layoutCount = count || 0 + next() + }) + }, + ensureProject: function (req, res, next) { if (req.params.slug) { Project.findOne({ slug: req.params.slug }, function(err, project){ -- cgit v1.2.3-70-g09d2 From 33e5644226649d277c6b84dc37fccdd5b7c6e86c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Aug 2015 12:23:35 -0400 Subject: more accurate counts --- public/assets/javascripts/ui/site/LayoutsModal.js | 10 ++-- server/lib/api/layouts.js | 4 +- server/lib/middleware.js | 60 +++++++++++++++++++++-- server/lib/schemas/Plan.js | 2 +- server/lib/schemas/Project.js | 1 + server/lib/views/staff.js | 45 ++++++++++++++++- views/staff/_nav.ejs | 1 + views/staff/plans/_form.ejs | 6 +-- views/staff/projects/index.ejs | 2 +- 9 files changed, 113 insertions(+), 18 deletions(-) (limited to 'server/lib/middleware.js') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 639d55c..f69b38f 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -16,13 +16,15 @@ var LayoutsIndex = View.extend({ populate: function(data){ /* - if (data.layoutCount > data.plan.basic_layout_limit) { + if (data.layoutCounts.basic > data.plan.basic_layout_limit) { } - if (data.projectCount > data.plan.stock_project_limit) { + if (data.layoutCounts.pro > data.plan.pro_layout_limit) { } - if (data.projectCount > data.plan.basic_project_limit) { + if (data.projectCounts.stock > data.plan.stock_project_limit) { } - if (data.projectCount > data.plan.pro_project_limit) { + if (data.projectCounts.basic > data.plan.basic_project_limit) { + } + if (data.projectCounts.pro > data.plan.pro_project_limit) { } */ if (! data.layouts.length) { diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index 7e7976c..1c87fae 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -16,8 +16,8 @@ var layouts = { layouts: docs, plan: middleware.plans[ res.locals.user.plan_level || 0 ], user: res.locals.user, - layoutCount: res.locals.layoutCount, - projectCount: res.locals.projectCount, + layoutCounts: res.locals.layoutCounts, + projectCounts: res.locals.projectCounts, }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 9d09a10..fe4dc49 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -60,20 +60,48 @@ var middleware = { res.locals.ogUrl = "http://vvalls.com/" res.locals.ogDescription = "3D gallery space, fully customizable" res.locals.ogAuthor = "VValls" - res.locals.plans = plans + res.locals.plans = middleware.plans res.locals.opt = {} next() }, ensureUserProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id }, function(err, count){ - res.locals.projectCount = count || 0 + var counts = { stock: 0, basic: 0, pro: 0 } + res.locals.projectCounts = counts + Project.count({ user_id: req.user.id, layout_type: 0 }, function(err, count){ + res.locals.projectCounts.stock = count || 0 + if (req.user.plan_level > 0) { return middleware.ensureBasicProjectsCount(req, res, next) } + else next() + }) + }, + ensureBasicProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ + res.locals.projectCounts.basic = count || 0 + if (req.user.plan_level > 1) { return middleware.ensureProProjectsCount(req, res, next) } + else next() + }) + }, + ensureProProjectsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ + res.locals.projectCounts.pro = count || 0 next() }) }, + ensureUserLayoutsCount: function(req, res, next){ - Layout.count({ user_id: req.user.id }, function(err, count){ - res.locals.layoutCount = count || 0 + var counts = { basic: 0, pro: 0 } + res.locals.layoutCounts = counts + if (req.user.plan_level == 0) { return next() } + + Layout.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ + res.locals.layoutCounts.basic = count || 0 + if (req.user.plan_level > 1) { return middleware.ensureProLayoutsCount(req, res, next) } + else next() + }) + }, + ensureProLayoutsCount: function(req, res, next){ + Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ + res.locals.layoutCounts.pro = count || 0 next() }) }, @@ -100,6 +128,28 @@ var middleware = { } }, + ensureLayout: function (req, res, next) { + if (req.params.slug) { + Layout.findOne({ slug: req.params.slug }, function(err, layout){ + if (err) { + console.error(err) + req.layout = null + } + else if (! project) { + req.layout = null + } + else { + req.layout = layout + } + next() + }) + } + else { + req.layout = null + next() + } + }, + ensureIsCollaborator: function(req, res, next) { req.isCollaborator = false req.isOwner = false diff --git a/server/lib/schemas/Plan.js b/server/lib/schemas/Plan.js index 8a19b99..388ce69 100644 --- a/server/lib/schemas/Plan.js +++ b/server/lib/schemas/Plan.js @@ -31,7 +31,7 @@ var PlanSchema = new mongoose.Schema({ permissions: { basic_editor: { type: Boolean, default: false }, pro_editor: { type: Boolean, default: false }, - solids: { type: Boolean, default: false }, + sculpture: { type: Boolean, default: false }, collaborators: { type: Boolean, default: false }, no_logo: { type: Boolean, default: false }, }, diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js index e9501fc..855d95a 100644 --- a/server/lib/schemas/Project.js +++ b/server/lib/schemas/Project.js @@ -39,6 +39,7 @@ var ProjectSchema = new mongoose.Schema({ created_at: { type: Date }, updated_at: { type: Date }, featured: { type: Boolean, default: false }, + layout_type: { type: Number, default: 0 }, }); module.exports = exports = mongoose.model('project', ProjectSchema); diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 19b361d..6c97bbd 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -21,7 +21,7 @@ var staff = module.exports = { plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " + "pro_layout_monthly_price pro_layout_yearly_price " + "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit", - plans_permissions: "basic_editor pro_editor solids collaborators no_logo", + plans_permissions: "basic_editor pro_editor sculpture collaborators no_logo", }, defaults: { @@ -401,6 +401,13 @@ var staff = module.exports = { return project }, + layout: function(layout){ + layout = layout.toObject() + layout.date = moment( layout.updated_at || layout.created_at ).format("M/DD/YYYY hh:mm a") + layout.user = {} + return layout + }, + media: function(media){ media = media.toObject() media.date = moment( media.updated_at || media.created_at ).format("M/DD/YYYY hh:mm a") @@ -520,7 +527,41 @@ var staff = module.exports = { staff.projects.feature ); - + + // + // layouts + + app.get('/staff/layouts', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureLayoutsCount, + + staff.middleware.ensureLayouts, + staff.middleware.ensureLayoutsUsers, + + staff.layouts.index + ); + app.get('/staff/layouts/:slug', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureLayout, + staff.middleware.ensureLayout, + staff.middleware.ensureLayoutUser, + + staff.layouts.show + ); + app.put('/staff/layouts/:slug/feature', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureLayout, + staff.middleware.ensureLayout, + + staff.layouts.make_stock + ); + // // media diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index a607638..3bb3b08 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -2,6 +2,7 @@ home users projects + layouts media plans diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs index 61be7e8..85375fa 100644 --- a/views/staff/plans/_form.ejs +++ b/views/staff/plans/_form.ejs @@ -124,9 +124,9 @@
  • - - - + + +
  • diff --git a/views/staff/projects/index.ejs b/views/staff/projects/index.ejs index e4ba469..1d309ce 100644 --- a/views/staff/projects/index.ejs +++ b/views/staff/projects/index.ejs @@ -7,7 +7,7 @@
    [[ include ../_pagination ]] -[[ include ../_projects ]] +[[ include ../_layouts ]] [[ include ../_pagination ]] [[ include ../_footer ]] -- cgit v1.2.3-70-g09d2 From 18e8ca03b90f124968400ccc742744c3ed01547a Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Aug 2015 18:36:25 -0400 Subject: cleanup --- public/assets/javascripts/ui/site/LayoutsModal.js | 2 +- server/lib/api/layouts.js | 17 +++++++------ server/lib/middleware.js | 29 ++++------------------- 3 files changed, 15 insertions(+), 33 deletions(-) (limited to 'server/lib/middleware.js') diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index b620b58..87251af 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -16,7 +16,7 @@ var LayoutsIndex = View.extend({ populate: function(data){ /* - if (data.user.plan_level < 1 && data.projectCounts.free == 1) { + if (data.user.plan_level < 1 && data.projectCount == 1) { // show lockout message } */ diff --git a/server/lib/api/layouts.js b/server/lib/api/layouts.js index a3edc38..f1db121 100644 --- a/server/lib/api/layouts.js +++ b/server/lib/api/layouts.js @@ -9,13 +9,16 @@ var _ = require('lodash'), var layouts = { index: function(req, res){ - Layout.find({}, function(err, docs){ - res.json({ - layouts: docs, - user: res.locals.user, - layoutCounts: res.locals.layoutCounts, - projectCounts: res.locals.projectCounts, - }) + Layout.find({ is_stock: true }, function(err, stock_layouts){ + Layout.find({ user_id: req.user._id }, function(err, user_layouts){ + res.json({ + layouts: stock_layouts, + user_layouts: user_layouts, + user: res.locals.user, + layoutCount: res.locals.layoutCount, + projectCount: res.locals.projectCount, + }) + }) }) }, diff --git a/server/lib/middleware.js b/server/lib/middleware.js index fe4dc49..94c4acd 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -68,22 +68,8 @@ var middleware = { ensureUserProjectsCount: function(req, res, next){ var counts = { stock: 0, basic: 0, pro: 0 } res.locals.projectCounts = counts - Project.count({ user_id: req.user.id, layout_type: 0 }, function(err, count){ - res.locals.projectCounts.stock = count || 0 - if (req.user.plan_level > 0) { return middleware.ensureBasicProjectsCount(req, res, next) } - else next() - }) - }, - ensureBasicProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ - res.locals.projectCounts.basic = count || 0 - if (req.user.plan_level > 1) { return middleware.ensureProProjectsCount(req, res, next) } - else next() - }) - }, - ensureProProjectsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ - res.locals.projectCounts.pro = count || 0 + Project.count({ user_id: req.user._id }, function(err, count){ + res.locals.projectCount = count || 0 next() }) }, @@ -93,15 +79,8 @@ var middleware = { res.locals.layoutCounts = counts if (req.user.plan_level == 0) { return next() } - Layout.count({ user_id: req.user.id, layout_type: 1 }, function(err, count){ - res.locals.layoutCounts.basic = count || 0 - if (req.user.plan_level > 1) { return middleware.ensureProLayoutsCount(req, res, next) } - else next() - }) - }, - ensureProLayoutsCount: function(req, res, next){ - Project.count({ user_id: req.user.id, layout_type: 2 }, function(err, count){ - res.locals.layoutCounts.pro = count || 0 + Layout.count({ user_id: req.user._id }, function(err, count){ + res.locals.layoutCount = count || 0 next() }) }, -- cgit v1.2.3-70-g09d2 From 71c3a4a02c7c46533aec836ef30a0d0ffa96399b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Aug 2015 18:20:22 -0400 Subject: layout stuff --- .../javascripts/mx/extensions/mx.movements.js | 6 +- .../assets/javascripts/mx/primitives/mx.image.js | 3 +- .../rectangles/engine/map/tools/ortho.js | 26 +- .../rectangles/engine/map/tools/polyline.js | 24 +- .../rectangles/engine/shapes/shapelist.js | 1 + public/assets/javascripts/ui/lib/Toolbar.js | 22 ++ public/assets/javascripts/ui/site/StaffView.js | 26 +- public/assets/test/ortho3.html | 38 +-- public/assets/test/ortho4.html | 261 +++++++++++++++++++++ server/lib/middleware.js | 2 +- server/lib/schemas/Media.js | 1 + server/lib/views/staff.js | 3 +- views/staff/_layouts.ejs | 2 +- views/staff/layouts/show.ejs | 4 +- 14 files changed, 352 insertions(+), 67 deletions(-) create mode 100644 public/assets/javascripts/ui/lib/Toolbar.js create mode 100644 public/assets/test/ortho4.html (limited to 'server/lib/middleware.js') diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js index fa59908..9ed8790 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -162,13 +162,13 @@ MX.Movements = function (cam) { case 8: // backspace e.preventDefault() - if (app.controller.sculptureEditor.sculpture) { + if (app.controller.sculptureEditor && app.controller.sculptureEditor.sculpture) { app.controller.sculptureEditor.sculpture.remove() } - else if (app.controller.mediaEditor.scenery) { + else if (app.controller.mediaEditor && app.controller.mediaEditor.scenery) { app.controller.mediaEditor.scenery.remove() } - else if (app.controller.textEditor.scenery) { + else if (app.controller.textEditor && app.controller.textEditor.scenery) { app.controller.textEditor.scenery.remove() } } diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index 64de4b2..f9de141 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -17,7 +17,7 @@ MX.Image = MX.Object3D.extend({ this.el.style.backgroundRepeat = 'no-repeat' - this.load(ops) + ops.src && this.load(ops) }, load: function(ops){ @@ -64,7 +64,6 @@ MX.Image = MX.Object3D.extend({ if (recenter) { ctx.restore() } - }, }) diff --git a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js index be3d707..ef41096 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js @@ -12,11 +12,11 @@ var OrthoPolylineTool = MapTool.extend(function (base) { if (map.ui.placing) { // close polyline or cancel map.ui.placing = false - if (line.points.length > 2) { - line.build() + if (shapes.workline.points.length > 2) { + shapes.workline.build() } else { - line.reset() + shapes.workline.reset() } return } @@ -29,24 +29,24 @@ var OrthoPolylineTool = MapTool.extend(function (base) { // compare to initial point var p = last_point.clone() if (map.ui.placing) { - if (line.lastPoint().eq(p)) { + if (shapes.workline.lastPoint().eq(p)) { return } - else if (line.canCloseWith(p)) { - line.close() - line.build() + else if (shapes.workline.canCloseWith(p)) { + shapes.workline.close() + shapes.workline.build() map.ui.placing = false } else { - line.add(p) + shapes.workline.add(p) prev_point = p horizontal = ! horizontal } } else { map.ui.placing = true - line = new Polyline () - line.add(p) + shapes.workline = new Polyline () + shapes.workline.add(p) first_point = prev_point = p horizontal = false } @@ -55,7 +55,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { last_point.a = cursor.x.a last_point.b = cursor.y.a if (map.ui.placing) { - if (line.points.length == 1) { + if (shapes.workline.points.length == 1) { var x = abs(prev_point.a - last_point.a) var y = abs(prev_point.b - last_point.b) if (x > y) { @@ -86,7 +86,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { } } - if (line.canCloseWith(last_point)) { + if (shapes.workline.canCloseWith(last_point)) { document.body.style.cursor = "pointer" last_point.assign(first_point) cursor.x.a = cursor.x.b = last_point.a @@ -107,7 +107,7 @@ var OrthoPolylineTool = MapTool.extend(function (base) { } } exports.cancel = function(){ - if (map.ui.placing) { line.reset() } + if (map.ui.placing) { shapes.workline.reset() } first_point = null map.ui.placing = false } diff --git a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js index 559aea8..1ab86f6 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js @@ -9,11 +9,11 @@ var PolylineTool = MapTool.extend(function (base) { if (map.ui.placing) { // close polyline or cancel map.ui.placing = false - if (line.points.length > 2) { - line.build() + if (shapes.workline.points.length > 2) { + shapes.workline.build() } else { - line.reset() + shapes.workline.reset() } return } @@ -24,27 +24,27 @@ var PolylineTool = MapTool.extend(function (base) { // compare to initial point var p = last_point.clone() if (map.ui.placing) { - if (line.canCloseWith(p)) { - line.close() - line.build() + if (shapes.workline.canCloseWith(p)) { + shapes.workline.close() + shapes.workline.build() map.ui.placing = false } else { - line.add(p) + shapes.workline.add(p) } } else { map.ui.placing = true - line = new Polyline () - line.add(p) + shapes.workline = new Polyline () + shapes.workline.add(p) } } exports.move = function(e, cursor){ last_point.a = cursor.x.a last_point.b = cursor.y.a - if (map.ui.placing && line.canCloseWith(last_point)) { + if (map.ui.placing && shapes.workline.canCloseWith(last_point)) { document.body.style.cursor = "pointer" - last_point.assign(line.points[0]) + last_point.assign(shapes.workline.points[0]) cursor.x.a = cursor.x.b = last_point.a cursor.y.a = cursor.y.b = last_point.b return @@ -62,7 +62,7 @@ var PolylineTool = MapTool.extend(function (base) { } } exports.cancel = function(){ - if (map.ui.placing) { line.reset() } + if (map.ui.placing) { shapes.workline.reset() } map.ui.placing = false } return exports diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js index 00e1a4e..932ce36 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js @@ -2,6 +2,7 @@ var ShapeList = Fiber.extend(function(base){ var exports = {} exports.init = function(){ this.shapes = [] + this.workline = null } exports.add = function(shape){ this.shapes.push(shape) diff --git a/public/assets/javascripts/ui/lib/Toolbar.js b/public/assets/javascripts/ui/lib/Toolbar.js new file mode 100644 index 0000000..a9ce51c --- /dev/null +++ b/public/assets/javascripts/ui/lib/Toolbar.js @@ -0,0 +1,22 @@ +var Toolbar = Fiber.extend(function(base){ + var exports = {} + exports.init = function(rapper){ + this.rapper = (typeof rapper == "string") ? $(rapper)[0] : rapper + this.tools = {} + this.els = {} + } + exports.add = function(role, fn){ + var self = this + this.tools[role] = fn + this.els[role] = $("[data-role=" + role + "]", self.rapper) + this.els[role].click(function(){ + $(".active", self.rapper).removeClass('active') + $(this).addClass('active') + fn() + }) + } + exports.pick = function(role){ + this.els[role].trigger("click") + } + return exports +}) \ No newline at end of file diff --git a/public/assets/javascripts/ui/site/StaffView.js b/public/assets/javascripts/ui/site/StaffView.js index 0398f71..59649e3 100644 --- a/public/assets/javascripts/ui/site/StaffView.js +++ b/public/assets/javascripts/ui/site/StaffView.js @@ -4,11 +4,13 @@ var StaffView = View.extend({ events: { "click #toggle-staff": "toggleStaff", "click #toggle-featured": "toggleFeatured", + "click #toggle-stock": "toggleStock", }, initialize: function() { this.$toggleStaff = $("#toggle-staff") this.$toggleFeatured = $("#toggle-featured") + this.$toggleStock = $("#toggle-stock") this.$mediaEmbed = $("#media-embed") if (this.$toggleStaff.length && this.$toggleStaff.data().isstaff) { this.$toggleStaff.html("Is Staff") @@ -16,6 +18,9 @@ var StaffView = View.extend({ if (this.$toggleFeatured.length && this.$toggleFeatured.data().featured) { this.$toggleFeatured.html("Featured Project") } + if (this.$toggleStock.length && this.$toggleStock.data().stock) { + this.$toggleStock.html("Layout is Stock") + } if (this.$mediaEmbed.length) { var media = this.$mediaEmbed.data() this.$mediaEmbed.html( Parser.tag( media ) ) @@ -67,6 +72,25 @@ var StaffView = View.extend({ $("#isFeaturedProject").html(data.state ? "yes" : "no") }.bind(this) }) - }, + }, + + toggleStock: function(){ + console.log("stock") + var state = ! this.$toggleStock.data().stock + $.ajax({ + type: "put", + dataType: "json", + url: window.location.href + "/stock", + data: { + state: state, + _csrf: $("#_csrf").val(), + }, + success: function(data){ + this.$toggleStock.data("stock", data.state) + this.$toggleStock.html(data.state ? "Stock Layout" : "Make this layout Stock") + $("#isStockLayout").html(data.state ? "yes" : "no") + }.bind(this) + }) + }, }) diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html index ef5732c..f41a0ba 100644 --- a/public/assets/test/ortho3.html +++ b/public/assets/test/ortho3.html @@ -80,6 +80,7 @@ body { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 94c4acd..04cb330 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -114,7 +114,7 @@ var middleware = { console.error(err) req.layout = null } - else if (! project) { + else if (! layout) { req.layout = null } else { diff --git a/server/lib/schemas/Media.js b/server/lib/schemas/Media.js index 8247467..f37fb12 100644 --- a/server/lib/schemas/Media.js +++ b/server/lib/schemas/Media.js @@ -42,6 +42,7 @@ var MediaSchema = new mongoose.Schema({ mute: { type: Boolean, default: false }, keyframe: { type: Number, default: 0.0 }, tag: { type: String, default: "" }, + scale: { type: Number, default: 1.0 }, widthDimension: { type: Number }, heightDimension: { type: Number }, diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index a3d5bea..43330e2 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -6,6 +6,7 @@ var User = require('../schemas/User'), Collaborator = require('../schemas/Collaborator'), Plan = require('../schemas/Plan'), Subscription = require('../schemas/Subscription'), + Layout = require('../schemas/Layout'), config = require('../../../config'), middleware = require('../middleware'), util = require('../util'), @@ -821,7 +822,7 @@ var staff = module.exports = { make_stock: function(req, res){ res.locals.layout.is_stock = req.body.state == "true" res.locals.layout.save(function(err, layout){ - res.json({ state: layout.featured }) + res.json({ state: layout.is_stock }) }) }, }, diff --git a/views/staff/_layouts.ejs b/views/staff/_layouts.ejs index 3f3e6b2..d97883b 100644 --- a/views/staff/_layouts.ejs +++ b/views/staff/_layouts.ejs @@ -1,5 +1,5 @@ -[[ layouts.forEach(function(project){ ]] +[[ layouts.forEach(function(layout){ ]]
    [[- layout.name ]] diff --git a/views/staff/layouts/show.ejs b/views/staff/layouts/show.ejs index 0a2014b..b66449f 100644 --- a/views/staff/layouts/show.ejs +++ b/views/staff/layouts/show.ejs @@ -45,14 +45,14 @@ featured? - [[- layout.plan_type == 0 ? "yes" : "no" ]] + [[- layout.is_stock ? "yes" : "no" ]]


    - +

    -- cgit v1.2.3-70-g09d2 From ebb9226fd5d37e8033e87e41b8ac0355d68f954c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 27 Aug 2015 18:00:57 -0400 Subject: staff area for blueprints --- .../rectangles/engine/shapes/regionlist.js | 64 +++++++++++++++------- .../rectangles/engine/shapes/shapelist.js | 3 + .../javascripts/ui/blueprint/BlueprintEditor.js | 8 +-- .../javascripts/ui/blueprint/BlueprintInfo.js | 23 ++++++++ public/assets/stylesheets/app.css | 9 +++ server/lib/middleware.js | 23 ++++++++ server/lib/views/staff/fields.js | 3 +- server/lib/views/staff/helpers.js | 7 +++ server/lib/views/staff/index.js | 53 ++++++++++++++++-- server/lib/views/staff/middleware.js | 55 +++++++++++++++++++ views/controls/blueprint/info.ejs | 7 +++ views/staff/_blueprints.ejs | 21 +++++++ views/staff/_nav.ejs | 1 + views/staff/blueprints/index.ejs | 13 +++++ views/staff/blueprints/show.ejs | 59 ++++++++++++++++++++ views/staff/blueprints/show_404.ejs | 9 +++ views/staff/layouts/show.ejs | 2 +- 17 files changed, 331 insertions(+), 29 deletions(-) create mode 100644 views/staff/_blueprints.ejs create mode 100644 views/staff/blueprints/index.ejs create mode 100644 views/staff/blueprints/show.ejs create mode 100644 views/staff/blueprints/show_404.ejs (limited to 'server/lib/middleware.js') diff --git a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js index 86269a6..0dd4a1e 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js @@ -10,10 +10,25 @@ var RegionList = (function(){ var RegionList = {} var regions = RegionList.regions + // Build a list of regions from the existing shapes. + // Operates on all the shapes at once. RegionList.build = function(){ - - // first, get the segments sorted right to left & top to bottom var segments = RegionList.getSortedSegments() + return RegionList.buildRoomsFromSegments(segments) + } + + // Build a list of regions from the individual shapes. + // Same, but operates on the shapes individually + RegionList.buildByShape = function(){ + var shapes = RegionList.getSortedSegmentsByShape() + var region_lists = shapes.map(function(shape){ + return RegionList.buildRoomsFromSegments(shape.segments) + }) + var regions = [] + return regions.concat.apply(regions, region_lists); + } + + RegionList.buildRoomsFromSegments = function(segments){ var rooms = [] var seen_rooms = {} @@ -172,31 +187,42 @@ var RegionList = (function(){ return rooms } - // Gets a list of polylines from the ShapeList and sorts the segments. RegionList.getSortedSegments = function(){ // get a list of all segments from these polylines var segments = shapes.getAllSegments() - // re-orient them so they're either facing up or right and make them into rects - segments = segments.map(function(segment){ - // vertical - if (segment[0].a == segment[1].a) { - if (segment[0].b > segment[1].b) { - segment.push(segment.shift()) - } - } - // horizontal - else if (segment[0].b == segment[1].b) { - if (segment[0].a > segment[1].a) { - segment.push(segment.shift()) - } - } - return new Rect( segment[0].a, segment[0].b, segment[1].a, segment[1].b ) - }) + segments = segments.map(RegionList.segmentsToRects) return sort.rects_by_position(segments) } + + RegionList.getSortedSegmentsByShape = function(){ + return shapes.getAllShapeSegments().map(function(shape){ + var segments = shape.map(RegionList.segmentsToRects) + return { + shape: shape, + segments: sort.rects_by_position(segments) + } + }) + } + + // re-orient a segment so it's either facing up or right and make it into a rect + RegionList.segmentsToRects = function(segment){ + // vertical + if (segment[0].a == segment[1].a) { + if (segment[0].b > segment[1].b) { + segment.push(segment.shift()) + } + } + // horizontal + else if (segment[0].b == segment[1].b) { + if (segment[0].a > segment[1].a) { + segment.push(segment.shift()) + } + } + return new Rect( segment[0].a, segment[0].b, segment[1].a, segment[1].b ) + } return RegionList diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js index e5a70fb..2d33af2 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js @@ -69,6 +69,9 @@ var ShapeList = Fiber.extend(function(base){ exports.forEach = function(fn){ this.shapes.forEach(fn) } + exports.getAllShapeSegments = function(){ + return this.shapes.map(function(shape){ return shape.getSegments() }) + } exports.getAllSegments = function(){ var segments = [] this.shapes.forEach(function(shape){ diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js index 7a1c064..7704689 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -82,7 +82,7 @@ var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ scale: media.scale, }) this.startAnimating() - this.regions = RegionList.build() + this.regions = RegionList.buildByShape() }, animate: function(t, dt){ @@ -114,9 +114,9 @@ var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ map.draw.camera(scene.camera) // var colors = ["rgba(0,0,0,0.1)"] -// var colors = ["rgba(255,255,255,1)"] -// -// map.draw.regions(this.regions, colors, "#000") +// var colors = ["rgba(255,255,255,1)"] + +// map.draw.regions(this.regions, colors, "#000") // this.regions.forEach(function(room,i){ // map.draw.ctx.fillStyle = colors[i % colors.length] diff --git a/public/assets/javascripts/ui/blueprint/BlueprintInfo.js b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js index 6dd6a7d..51b310e 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintInfo.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintInfo.js @@ -10,6 +10,7 @@ var BlueprintInfo = View.extend({ "change [name=units]": 'changeUnits', "keydown [name=viewHeight]": 'enterViewHeight', "change [name=viewHeight]": 'changeViewHeight', + "click .openScaler": 'openScaler', }, initialize: function(opt){ @@ -18,13 +19,30 @@ var BlueprintInfo = View.extend({ this.$units = this.$("[name=units]") this.$viewHeight = this.$("[name=viewHeight]") this.$unitName = this.$(".unitName") + this.$blueprintScaleDisplay = this.$("#blueprintScaleDisplay") }, load: function(data){ this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight ) this.$height.unitVal( window.wallHeight = data.wallHeight || app.defaults.wallHeight ) this.$units.val( data.units ) + this.$('span.units').html( data.units ) this.$unitName.html( data.units ) + + var resolution + switch (data.units) { + case 'ft': + resolution = app.defaults.footResolution + break + case 'm': + resolution = app.defaults.meterResolution + break + case 'px': + default: + resolution = 1 + break + } + this.$blueprintScaleDisplay.html( ((1/data.scale) * resolution).toFixed(1) ) this.show() }, @@ -33,6 +51,11 @@ var BlueprintInfo = View.extend({ this.$viewHeight.unitVal( window.viewHeight ) }, + openScaler: function(){ + this.parent.scaler.pick( this.parent.data, true ) + this.parent.scaler.show() + }, + show: function(){ this.toggle(true) }, diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index e4f1b27..1154fde 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -2505,6 +2505,9 @@ input[type="range"]::-webkit-slider-thumb { top: 5px; font-weight:600; } +.setting.number.scale label { + top: 0; +} .setting.number label:after { content:":"; } @@ -3328,6 +3331,7 @@ a[data-role="forgot-password"] { padding: 0px; position: relative; display: inline-block; + margin: 0 2px; } .blueprints .blueprint img { height: 100px; @@ -3364,6 +3368,11 @@ a[data-role="forgot-password"] { [data-role="create-new-blueprint"] { margin-bottom: 10px; } +.openScaler { + margin-left: 10px; + border-bottom: 1px solid; + cursor: pointer; +} /* KEYBOARD SHORTCUTS */ diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 04cb330..0a0a9ce 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -8,6 +8,7 @@ var passport = require('passport'), Collaborator = require('./schemas/Collaborator'), Project = require('./schemas/Project'), Layout = require('./schemas/Layout'), + Blueprint = require('./schemas/Blueprint'), Plan = require('./schemas/Plan'); @@ -129,6 +130,28 @@ var middleware = { } }, + ensureBlueprint: function (req, res, next) { + if (req.params.slug) { + Blueprint.findOne({ slug: req.params.slug }, function(err, blueprint){ + if (err) { + console.error(err) + req.blueprint = null + } + else if (! blueprint) { + req.blueprint = null + } + else { + req.blueprint = blueprint + } + next() + }) + } + else { + req.blueprint = null + next() + } + }, + ensureIsCollaborator: function(req, res, next) { req.isCollaborator = false req.isOwner = false diff --git a/server/lib/views/staff/fields.js b/server/lib/views/staff/fields.js index 57eea7e..84c1efa 100644 --- a/server/lib/views/staff/fields.js +++ b/server/lib/views/staff/fields.js @@ -1,7 +1,8 @@ module.exports = { user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip", project: "_id name slug user_id privacy layout_type created_at updated_at", - layout: "_id name slug user_id layout_type created_at updated_at", + layout: "_id name slug user_id layout_type is_stock created_at updated_at", + blueprint: "_id name slug user_id created_at updated_at", plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " + "pro_layout_monthly_price pro_layout_yearly_price " + "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit", diff --git a/server/lib/views/staff/helpers.js b/server/lib/views/staff/helpers.js index 57383f4..ff4065a 100644 --- a/server/lib/views/staff/helpers.js +++ b/server/lib/views/staff/helpers.js @@ -27,6 +27,13 @@ module.exports = { layout.user = {} return layout }, + + blueprint: function(blueprint){ + blueprint = blueprint.toObject() + blueprint.date = moment( blueprint.updated_at || blueprint.created_at ).format("M/DD/YYYY hh:mm a") + blueprint.user = {} + return blueprint + }, media: function(media){ media = media.toObject() diff --git a/server/lib/views/staff/index.js b/server/lib/views/staff/index.js index 033fc88..49a0384 100644 --- a/server/lib/views/staff/index.js +++ b/server/lib/views/staff/index.js @@ -7,6 +7,7 @@ var User = require('../../schemas/User'), Plan = require('../../schemas/Plan'), Subscription = require('../../schemas/Subscription'), Layout = require('../../schemas/Layout'), + Blueprint = require('../../schemas/Blueprint'), config = require('../../../../config'), middleware = require('../../middleware'), util = require('../../util'), @@ -159,7 +160,32 @@ var staff = module.exports = { staff.layouts.make_stock ); - + + // + // blueprints + + app.get('/staff/blueprints', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureBlueprintsCount, + + staff.middleware.ensureBlueprints, + staff.middleware.ensureBlueprintsUsers, + + staff.blueprints.index + ); + app.get('/staff/blueprints/:slug', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + middleware.ensureBlueprint, + staff.middleware.ensureBlueprint, + staff.middleware.ensureBlueprintUser, + + staff.blueprints.show + ); + // // media @@ -321,7 +347,7 @@ var staff = module.exports = { }, // /staff/projects/ - // /staff/projects/:name + // /staff/projects/:slug projects: { index: function(req, res){ res.locals.pagination.count = res.locals.projects.length @@ -350,7 +376,7 @@ var staff = module.exports = { }, // /staff/layouts/ - // /staff/layouts/:name + // /staff/layouts/:slug layouts: { index: function(req, res){ res.locals.pagination.count = res.locals.layouts.length @@ -374,7 +400,26 @@ var staff = module.exports = { }) }, }, - + + // /staff/blueprints/ + // /staff/blueprints/:slug + blueprints: { + index: function(req, res){ + res.locals.pagination.count = res.locals.blueprints.length + res.locals.pagination.max = res.locals.blueprintCount + staff.paginate(req, res) + res.render('staff/blueprints/index') + }, + show: function(req, res){ + if (res.locals.blueprint) { + res.render('staff/blueprints/show', { + }) + } + else { + res.render('staff/blueprints/show_404') + } + }, + }, media: { index: function(req, res){ diff --git a/server/lib/views/staff/middleware.js b/server/lib/views/staff/middleware.js index 1ea98e9..03fda2e 100644 --- a/server/lib/views/staff/middleware.js +++ b/server/lib/views/staff/middleware.js @@ -6,6 +6,7 @@ var User = require('../../schemas/User'), Plan = require('../../schemas/Plan'), Subscription = require('../../schemas/Subscription'), Layout = require('../../schemas/Layout'), + Blueprint = require('../../schemas/Blueprint'), util = require('../../util'), fields = require('./fields'), helpers = require('./helpers'), @@ -128,6 +129,35 @@ var middleware = module.exports = { }) }, + ensureBlueprints: 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) { + default: + case 'date': + sort = {'updated_at': -1} + break + case 'name': + paginationInfo.sort = "name" + sort = {'slug': 1} + break + } + Blueprint.find(criteria) + .select(fields.blueprint) + .sort(sort) + .skip(offset) + .limit(limit) + .exec(function (err, blueprints) { + res.locals.blueprints = blueprints.map(helpers.blueprint) + next() + }) + }, + ensureMedia: function(req, res, next){ var paginationInfo = res.locals.pagination = {} var criteria = req.criteria || {} @@ -240,6 +270,11 @@ var middleware = module.exports = { middleware.ensureObjectsUsers(res.locals.layouts, next) }, + ensureBlueprintsUsers: function(req, res, next){ + if (! res.locals.blueprints || ! res.locals.blueprints.length) { return next() } + middleware.ensureObjectsUsers(res.locals.blueprints, next) + }, + ensureSubscriptionsUsers: function(req, res, next){ if (! res.locals.subscriptions || ! res.locals.subscriptions.length) { return next() } middleware.ensureObjectsUsers(res.locals.subscriptions, next) @@ -345,6 +380,13 @@ var middleware = module.exports = { }) }, + ensureBlueprintsCount: function(req, res, next){ + Blueprint.count({}, function(err, count){ + res.locals.blueprintCount = count || 0 + next() + }) + }, + ensureMediaCount: function(req, res, next){ Media.count({}, function(err, count){ res.locals.mediaCount = count || 0 @@ -418,4 +460,17 @@ var middleware = module.exports = { }) }, + ensureBlueprint: function(req, res, next){ + res.locals.blueprint = req.blueprint + next() + }, + ensureBlueprintUser: function(req, res, next){ + if (! res.locals.blueprint) { return next() } + User.findOne({ _id: res.locals.blueprint.user_id }, fields.user, function(err, user){ + res.locals.blueprintUser = helpers.user(user) || defaults.user + next() + }) + }, + + } \ No newline at end of file diff --git a/views/controls/blueprint/info.ejs b/views/controls/blueprint/info.ejs index 4e2316f..a86481b 100644 --- a/views/controls/blueprint/info.ejs +++ b/views/controls/blueprint/info.ejs @@ -20,4 +20,11 @@ +
    + + + px/ + [edit scale] +
    + diff --git a/views/staff/_blueprints.ejs b/views/staff/_blueprints.ejs new file mode 100644 index 0000000..58fe2a3 --- /dev/null +++ b/views/staff/_blueprints.ejs @@ -0,0 +1,21 @@ + +[[ blueprints.forEach(function(blueprint){ ]] + + + + + + +[[ }) ]] +
    + [[- blueprint.name ]] + + [[- blueprint.user.username ]] + + [[- blueprint.date ]] +
    diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index 3bb3b08..702a374 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -3,6 +3,7 @@ users projects layouts + blueprints media plans diff --git a/views/staff/blueprints/index.ejs b/views/staff/blueprints/index.ejs new file mode 100644 index 0000000..2206a1c --- /dev/null +++ b/views/staff/blueprints/index.ejs @@ -0,0 +1,13 @@ +[[ include ../_header ]] + +

    Blueprints

    + +[[ include ../_nav ]] + +
    + +[[ include ../_pagination ]] +[[ include ../_blueprints ]] +[[ include ../_pagination ]] + +[[ include ../_footer ]] diff --git a/views/staff/blueprints/show.ejs b/views/staff/blueprints/show.ejs new file mode 100644 index 0000000..5fd9db6 --- /dev/null +++ b/views/staff/blueprints/show.ejs @@ -0,0 +1,59 @@ +[[ include ../_header ]] + +

    [[- blueprint.name ]]

    + +[[ include ../_nav ]] + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + [[- blueprint.name ]] + + [[- blueprint.date ]] +
    + [[ if (blueprintUser.photo) { ]] +
    + [[ } ]] + [[- blueprintUser.username ]] +
    + +
    Width[[- blueprint.width ]]
    Height[[- blueprint.height ]]
    Scale[[- blueprint.scale ]]
    + +

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

    Blueprint not found

    + +[[ include ../_nav ]] + +
    + +[[ include ../_footer ]] diff --git a/views/staff/layouts/show.ejs b/views/staff/layouts/show.ejs index b66449f..2742c1f 100644 --- a/views/staff/layouts/show.ejs +++ b/views/staff/layouts/show.ejs @@ -42,7 +42,7 @@ - featured? + stock layout? [[- layout.is_stock ? "yes" : "no" ]] -- cgit v1.2.3-70-g09d2