From 5dd9742da846e8db863a951f1502d0edf5a3f90b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 7 Jan 2015 18:02:13 -0500 Subject: forms for editing plans --- views/staff/_nav.ejs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 views/staff/_nav.ejs (limited to 'views/staff/_nav.ejs') diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs new file mode 100644 index 0000000..2115e9f --- /dev/null +++ b/views/staff/_nav.ejs @@ -0,0 +1,6 @@ + \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 664099f91ae3ed2d667d331b19c2e41dec60124c Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 9 Jan 2015 06:43:31 -0500 Subject: fix up plans form --- public/assets/stylesheets/app.css | 6 +- public/assets/stylesheets/staff.css | 16 ++++ server/lib/views/staff.js | 70 ++++++++++++---- server/repl.js | 2 + views/staff/_nav.ejs | 1 + views/staff/index.ejs | 6 +- views/staff/plans/_form.ejs | 160 ++++++++++++++++++++++-------------- views/staff/plans/edit.ejs | 2 +- views/staff/plans/index.ejs | 11 ++- views/staff/plans/new.ejs | 4 +- 10 files changed, 186 insertions(+), 92 deletions(-) (limited to 'views/staff/_nav.ejs') diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 0463e26..9e86ac3 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -2478,7 +2478,7 @@ form li { form label { float:left; } -form input[type="text"],form input[type="password"] { +form input[type="text"],form input[type="password"],form input[type="number"] { border: 1px solid; font-size: 20px; padding: 5px; @@ -3048,8 +3048,8 @@ a[data-role="forgot-password"] { form li { font-size: 16px; } - form input[type="text"], form input[type="password"] { - font-size: 15px; + form input[type="text"],form input[type="password"],form input[type="number"] { + font-size: 15px; } .page h1 { font-size: 26px; diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index de31571..e5cafa2 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -71,6 +71,22 @@ hr { color: #00f; border-bottom: 1px solid; } +.staff form { + max-width: none; + width: 600px; + padding: 20px; +} +.staff form label { + float: none; +} +.staff form p { + width: 350px; + margin: 5px 0; + color: #444; +} +.staff form div li { + width: 180px; +} #iframe-embed, #iframe-embed tr, #iframe-embed td { width: 79vw; } diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index ce676ed..6639137 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -18,6 +18,10 @@ var staff = module.exports = { fields: { user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip", project: "_id name slug user_id privacy 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", + plans_permissions: "basic_editor pro_editor solids collaborators no_logo", }, defaults: { @@ -122,8 +126,8 @@ var staff = module.exports = { }, ensurePlans: function(req, res, next){ - Plan.exec(function (err, plans) { - res.locals.plans = plans.map(staff.helpers.plan) + Plan.find(function (err, plans) { + res.locals.plans = (plans || []).map(staff.helpers.plan) next() }) }, @@ -132,17 +136,16 @@ var staff = module.exports = { Plan.findOne({ slug: req.params.slug }, function(err, plan){ if (err || ! plan) { console.error(err) - req.plan = null + res.redirect("/staff/plans/") } else { req.plan = plan + next() } - next() }) } else { - req.plan = null - next() + res.redirect("/staff/plans/") } }, @@ -326,7 +329,14 @@ var staff = module.exports = { media.user = {} media.shortUrl = media.url.replace(/^http.:\/\//,"") return media - } + }, + + plan: function(plan){ + plan = plan.toObject() + plan.date = moment( plan.updated_at || plan.created_at ).format("M/DD/YYYY hh:mm a") + plan.user = {} + return plan + }, }, route: function(app){ @@ -452,7 +462,8 @@ var staff = module.exports = { // // plans - app.get('/staff/plans/', + + app.get('/staff/plans', middleware.ensureAuthenticated, middleware.ensureIsStaff, @@ -484,6 +495,8 @@ var staff = module.exports = { middleware.ensureAuthenticated, middleware.ensureIsStaff, + staff.middleware.ensurePlan, + staff.plans.update ); }, @@ -607,14 +620,8 @@ var staff = module.exports = { plans: { index: function(req, res){ - res.locals.fields = ( - "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" - ).split(" ") - - res.locals.permissions = "basic_editor pro_editor solids collaborators no_logo".split(" ") - + res.locals.fields = staff.fields.plans.split(" ") + res.locals.permissions = staff.fields.plans_permissions.split(" ") res.render('staff/plans/index') }, new: function(req, res){ @@ -625,10 +632,37 @@ var staff = module.exports = { res.render('staff/plans/edit') }, create: function(req, res){ - res.redirect("/staff/plans/") + var plan = new Plan () + var fields = staff.fields.plans.split(" ") + var permissions = staff.fields.plans_permissions.split(" ") + + var data = util.cleanQuery(req.body) + data.name = util.sanitize(data.name) + data.slug = util.sanitize(data.slug.toLowerCase()) + + permissions.forEach(function(field){ + data[field] = data["permissions_" + field] + }) + + new Plan (data).save(function(err, doc){ + if (err || ! doc) { return res.json({ error: err }) } + res.redirect("/staff/plans/") + }) }, update: function(req, res){ - res.redirect("/staff/plans/") + var data = util.cleanQuery(req.body) + data.name = util.sanitize(data.name) + data.slug = util.sanitize(data.slug.toLowerCase()) + + _.extend(req.plan, data) + permissions.forEach(function(field){ + req.plan[field] = data["permissions_" + field] + }) + + req.plan.save(function(err, doc){ + if (err || ! doc) { return res.json({ error: err }) } + res.redirect("/staff/plans/") + }) }, } diff --git a/server/repl.js b/server/repl.js index ba94d45..353d8c5 100644 --- a/server/repl.js +++ b/server/repl.js @@ -9,6 +9,8 @@ mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){ "./lib/schemas/Layout", "./lib/schemas/Media", "./lib/schemas/Project", + "./lib/schemas/Plan", + "./lib/schemas/Subscription", ].forEach(function(modName){ // console.log(name, modName) var namez = modName.split("/"), name = namez[namez.length-1]; diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index 2115e9f..db7bedb 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -3,4 +3,5 @@ users projects media + plans \ No newline at end of file diff --git a/views/staff/index.ejs b/views/staff/index.ejs index 5ca7269..1b73641 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -2,11 +2,7 @@

Staff Area

- + [[ include _nav ]]
diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs index b97716f..fc86516 100644 --- a/views/staff/plans/_form.ejs +++ b/views/staff/plans/_form.ejs @@ -1,109 +1,149 @@ + -
+
    + +
  • +

    New Plan

    +
  • + +
  • - -
+
+ -
+
  • - -
  • +
    + -
    +
  • +

    Plan Pricing

    +
  • + +
  • - -
  • +
    + -
    +
  • - -
  • +
    + + +

    + Note: Pricing should be in cents, i.e. a price of $10.00 should be entered as 1000. +

    -
    - - -
    +
  • +

    Additional Template Pricing

    +
  • -
    - - -
    +
  • + +
    +
  • -
    - - -
    +
  • + +
    +
  • -
    - - -
    +
  • + +
    +
  • + +
  • + +
    +
  • -
    - - -
    +
  • +

    Per-Plan Template Limits

    +
  • -
    - - -
    +
  • + +
    +
  • + +
  • + +
    +
  • -
    +
  • +

    Per-Plan Project Limits

    +
  • + +
  • - -
  • +
    + -
    +
  • - -
  • +
    + -
    +
  • - -
  • +
    + +
  • +

    Permissions

    +
  • +
    - +
  • -
  • + + -
    - +
  • -
  • + + -
    - +
  • -
  • + + -
    - +
  • -
  • + + -
    - +
  • -
  • + + + +

    + These permissions should harmonize with the restrictions on layouts set above. +

    + - +
  • + +
  • + diff --git a/views/staff/plans/edit.ejs b/views/staff/plans/edit.ejs index 503c97d..9848873 100644 --- a/views/staff/plans/edit.ejs +++ b/views/staff/plans/edit.ejs @@ -7,7 +7,7 @@
    -[[- include form ]] +[[- include _form ]]
    [[ include ../_footer ]] diff --git a/views/staff/plans/index.ejs b/views/staff/plans/index.ejs index aa6c35a..121a2fc 100644 --- a/views/staff/plans/index.ejs +++ b/views/staff/plans/index.ejs @@ -6,6 +6,7 @@
    +[[ if (plans.length) { ]] @@ -30,7 +31,11 @@ [[ plans.forEach(function(plan){ ]] [[ }) ]] @@ -46,8 +51,10 @@ [[ }) ]] [[ }) ]] -
    [[- field.replace(/_/," ") ]] - [[- plan[field] ]] + [[ if (field.indexOf("_price") != -1) { ]] + [[- plan[field] == 0 ? "" : "$" + (plan[field]/100).toFixed(2) ]] + [[ } else { ]] + [[- plan[field] ]] + [[ } ]]
    +
    +[[ } ]] + New Plan
    diff --git a/views/staff/plans/new.ejs b/views/staff/plans/new.ejs index d56a1c3..297d3d6 100644 --- a/views/staff/plans/new.ejs +++ b/views/staff/plans/new.ejs @@ -7,9 +7,7 @@
    -[[- include form ]] +[[- include _form ]]
    [[ include ../_footer ]] - - -- cgit v1.2.3-70-g09d2 From afce400c65f362f7dd6307a5670dc3873d74ab79 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Sun, 11 Jan 2015 21:42:45 -0500 Subject: stub in subscriptions admin pages --- server/lib/views/staff.js | 34 +++++++++++++++++++++++++++++++++- views/staff/_nav.ejs | 1 + views/staff/subscriptions/index.ejs | 36 ++++++++++++++++++++++++++++++++++++ views/staff/subscriptions/show.ejs | 12 ++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 views/staff/subscriptions/index.ejs create mode 100644 views/staff/subscriptions/show.ejs (limited to 'views/staff/_nav.ejs') diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index 97ecde6..4351ef0 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -500,6 +500,27 @@ var staff = module.exports = { staff.plans.update ); + + // + // subscriptions + app.get('/staff/subscriptions', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureSubscriptions, + staff.middleware.ensureSubscriptionsUsers, + + staff.subscriptions.index + ); + app.get('/staff/subscriptions/:id', + middleware.ensureAuthenticated, + middleware.ensureIsStaff, + + staff.middleware.ensureSubscription, + staff.middleware.ensureSubscriptionUser, + + staff.subscriptions.edit + ); }, paginate: function(req, res){ @@ -669,6 +690,17 @@ var staff = module.exports = { res.redirect("/staff/plans/") }) }, - } + }, + + subscriptions: { + index: function(req, res){ + res.locals.subscriptions = req.subscriptions + res.render('staff/plans/index') + }, + show: function(req, res){ + res.locals.subscription = req.subscription + res.render('staff/plans/show') + }, + }, } diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index db7bedb..e79ff69 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -4,4 +4,5 @@ projects media plans + subscriptions \ No newline at end of file diff --git a/views/staff/subscriptions/index.ejs b/views/staff/subscriptions/index.ejs new file mode 100644 index 0000000..d1c0588 --- /dev/null +++ b/views/staff/subscriptions/index.ejs @@ -0,0 +1,36 @@ +[[ include ../_header ]] + +

    Users

    + +[[ include ../_nav ]] + +
    + +[[ include ../_pagination ]] + + +[[ subscriptions.forEach(function(subscription){ ]] + + + + + + + +[[ }) ]] +
    +
    +
    + [[- subscription.user.username ]] + + [[- subscription.user.displayName ]] + + [[- subscription.user.last_seen ]] +
    + + +[[ include ../_pagination ]] + +[[ include ../_footer ]] diff --git a/views/staff/subscriptions/show.ejs b/views/staff/subscriptions/show.ejs new file mode 100644 index 0000000..e2839a6 --- /dev/null +++ b/views/staff/subscriptions/show.ejs @@ -0,0 +1,12 @@ +[[ include ../_header ]] +

    User: [[- subscription.user.username ]]

    + +[[ include ../_nav ]] + +
    + +
    +info to show..
    +- link to recurly profile
    +- link to vvalls profile
    +- subscription tier + add-ons
    -- 
    cgit v1.2.3-70-g09d2
    
    
    From e7ecd5b141945a9c9ca7a57df643eaa3f3fdc3d6 Mon Sep 17 00:00:00 2001
    From: Jules Laplace 
    Date: Mon, 2 Feb 2015 09:43:06 -0500
    Subject: double checking all plan changes.. need to pass full plan info to
     update
    
    ---
     public/assets/javascripts/ui/site/EditSubscriptionModal.js |  3 +--
     server/lib/api/subscription.js                             | 10 ++++++----
     views/staff/_nav.ejs                                       |  2 +-
     3 files changed, 8 insertions(+), 7 deletions(-)
    
    (limited to 'views/staff/_nav.ejs')
    
    diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
    index 55ff3b5..c276354 100644
    --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js
    +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js
    @@ -224,14 +224,13 @@ var EditSubscriptionModal = ModalView.extend({
     		var is_changed = false
     		var diff = {}
     		"plan_type basic_layouts pro_layouts".split(" ").forEach(function(field){
    +			diff[field] = this.tempSubscriber[field]
     			if (this.tempSubscriber[field] != this.subscriber[field]) {
    -				diff[field] = this.tempSubscriber[field]
     				is_changed = true
     			}
     		}.bind(this))
     		
     		if (is_changed) {
    -			diff.plan_type = this.tempSubscriber.plan_type
     			this.update(diff)
     		}
     		this.subscriber = this.tempSubscriber
    diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js
    index 7e9221a..9c2d6ef 100644
    --- a/server/lib/api/subscription.js
    +++ b/server/lib/api/subscription.js
    @@ -142,6 +142,7 @@ var subscription = module.exports = {
         var plan_type = req.body.plan_type
         var basic_layouts = Math.max(0, parseInt(req.body.basic_layouts || 0, 10))
         var pro_layouts = Math.max(0, parseInt(req.body.pro_layouts || 0, 10))
    +    if (plan_type != "pro") { pro_layouts = 0 }
         
         if (plan_type == subscription.plan_type
     			&& basic_layouts == subscriber.basic_layouts
    @@ -149,15 +150,14 @@ var subscription = module.exports = {
         	return res.json(subscriber)
         }
     
    -    var data = {}
    +    var data = { subscription_add_ons: [] }
         data.plan_code = plan_type + "-monthly"
    -    data.subscription_add_ons = []
         
    -    if (plan_levels[plan_type] > 0) {
    +    if (plan_levels[plan_type] > 0 && basic_layouts > 0) {
           data.subscription_add_ons.push({ add_on_code: "extra-basic-layout", quantity: basic_layouts })
         }
         
    -    if (plan_type == "pro") {
    +    if (plan_type == "pro" && pro_layouts > 0) {
           data.subscription_add_ons.push({ add_on_code: "extra-pro-layout", quantity: pro_layouts })
         }
         
    @@ -165,7 +165,9 @@ var subscription = module.exports = {
         // data.subscription_add_ons = []
         //   add_on.add_on_code
         //   add_on.quantity
    +    console.log(data)
         recurly.subscriptions.update(subscriber.uuid, data, function(err, data){
    +    	console.log("got response from RECURLY ...")
         	if (err) {
         		console.log("error updating recurly subscription", err)
         		return res.json({ error: err })
    diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs
    index e79ff69..a607638 100644
    --- a/views/staff/_nav.ejs
    +++ b/views/staff/_nav.ejs
    @@ -4,5 +4,5 @@
       projects
       media
       plans
    -  subscriptions
    +
     
    \ No newline at end of file
    -- 
    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 'views/staff/_nav.ejs')
    
    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 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 'views/staff/_nav.ejs') 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