From 2d4ed7d888727e1b973c2581b694d900e30c2ebd Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 7 Jan 2015 13:53:27 -0500 Subject: plan/subscription schemas --- server/lib/views/index.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'server/lib/views/index.js') diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 8c3e63d..3326499 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -21,6 +21,7 @@ marked.setOptions({ var views = module.exports = { staff: require('./staff'), + subscription: require('./subscription'), editor_new: function (req, res) { if (! req.user) { @@ -88,13 +89,6 @@ var views = module.exports = { }, home: function (req, res) { - // while in development, blank homepage if not logged in -/* - if (! req.user) { - res.send("") - return - } -*/ views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ res.render('home', { projects: projects || [] -- cgit v1.2.3-70-g09d2 From 9c6f8f8568d20d75eb22955dbf2752ea777e59f8 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 7 Jan 2015 14:34:41 -0500 Subject: stub in brochure page --- public/assets/stylesheets/app.css | 14 +++++++ server/lib/schemas/Plan.js | 6 +++ server/lib/schemas/Subscription.js | 2 +- server/lib/views/index.js | 5 +++ server/lib/views/subscription.js | 1 - views/about/_blank.ejs | 2 +- views/about/about.ejs | 16 +------- views/about/brochure.ejs | 79 ++++++++++++++++++++++++++++++++++++++ views/about/howto.ejs | 2 +- views/builder.ejs | 2 +- views/docs.ejs | 2 +- views/editor.ejs | 2 +- views/home.ejs | 2 +- views/modal.ejs | 2 +- views/profile.ejs | 2 +- views/reader.ejs | 2 +- views/staff/_header.ejs | 2 +- 17 files changed, 116 insertions(+), 27 deletions(-) create mode 100644 views/about/brochure.ejs (limited to 'server/lib/views/index.js') diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index aecd6be..0463e26 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -673,7 +673,21 @@ iframe.embed { font-weight: 300; } +.aboutintro { + text-align: center; + line-height: 43px; + font-size: 24px; + padding: 5% 0; + font-weight: 300; +} +.aboutintro .inner { + max-width: 800px; + margin: 0 auto; + text-align: center; +} + /* PROFILE PAGE */ + .profilePic { background-size: cover; background-position: center; diff --git a/server/lib/schemas/Plan.js b/server/lib/schemas/Plan.js index 3e74997..1057bb2 100644 --- a/server/lib/schemas/Plan.js +++ b/server/lib/schemas/Plan.js @@ -13,6 +13,12 @@ var PlanSchema = new mongoose.Schema({ monthly_price: { type: Number }, yearly_price: { type: Number }, + basic_layout_monthly_price: { type: Number }, + basic_layout_yearly_price: { type: Number }, + + pro_layout_monthly_price: { type: Number }, + pro_layout_yearly_price: { type: Number }, + basic_layout_limit: { type: Number }, pro_layout_limit: { type: Number }, diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 8d0b10e..8315009 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -15,7 +15,7 @@ var SubscriptionSchema = new mongoose.Schema({ plans: [{ tier: { type: String }, monthly: { type: Boolean }, - }] + }], created_at: { type: Date, default: Date.now }, updated_at: { type: Date, default: Date.now }, diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 3326499..5f9088b 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -111,6 +111,11 @@ var views = module.exports = { res.render('about/' + name) return } + if (name == "brochure") { + // TODO: fetch plans + res.render('about/' + name) + return + } if (name == "about" || name == "index") { res.render('about/' + name) return diff --git a/server/lib/views/subscription.js b/server/lib/views/subscription.js index 77db1a0..ba54bb4 100644 --- a/server/lib/views/subscription.js +++ b/server/lib/views/subscription.js @@ -12,7 +12,6 @@ var subscription = 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", }, defaults: { diff --git a/views/about/_blank.ejs b/views/about/_blank.ejs index 0e9ea7e..3c23fa7 100644 --- a/views/about/_blank.ejs +++ b/views/about/_blank.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include ../partials/meta ]] diff --git a/views/about/about.ejs b/views/about/about.ejs index dd536be..2aec982 100644 --- a/views/about/about.ejs +++ b/views/about/about.ejs @@ -1,7 +1,7 @@ - vvalls + About VValls [[ include ../partials/meta ]] @@ -50,17 +50,3 @@ [[ include ../partials/scripts ]] - \ No newline at end of file diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs new file mode 100644 index 0000000..00083cf --- /dev/null +++ b/views/about/brochure.ejs @@ -0,0 +1,79 @@ + + + + VValls Subscriptions + [[ include ../partials/meta ]] + + +
+ [[ include ../partials/header ]] + +

Subscriptions

+ +
+
+ Want to get more out of VValls? Consider becoming a subscription user. +
+
+ +
+

[[- plans.free.name ]]

+
    +
  • One exhibition with pre-designed template floor plan +
+
+ +
+

[[- plans.premium.name ]]

+
    +
  • $[[- plans.premium.monthly_price ]]/mo or $[[- plans.premium.yearly_price ]]/year +
  • [[- plans.premium.stock_layout_project_limit ]] exhibitions included with pre-designed template floor plans +
  • Each new basic floor plan costs $[[- plans.premium.basic_layout_monthly_price ]]/mo + or $[[- plans.premium.basic_layout_yearly_price ]]/year, minimum 3 months +
  • Each new basic floor plan can have up to [[- plans.premium.basic_layout_project_limit ]] exhibitions +
  • VValls logo appears when embedding an exhibition on a web page +
+
+ +
+

[[- plans.pro.name ]]

+
    +
  • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year +
  • Comes with [[- plans.premium.pro_layout_limit ]] pro floor plan and [[- plans.premium.pro_layout_project_limit ]] exhibitions +
  • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo + or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months +
  • Each new pro floor plan can have up to [[- plans.pro.pro_layout_project_limit ]] exhibitions +
  • Includes planning for 3D objects in the room +
  • No VValls logo on embed +
+
+ +
+ Buying any extra floor plan unlocks collaboration. Invite an artist or curator to work on the exhibition with you. +
+ +
+ Basic Floor plan: Rectangle-based design of any dimension. +
+ +
+ Pro Floor plan: Trace an arbitrary floorplan. +
+ + +
+

Custom

+ We offer many types of customizations and white-label options for business and educational uses. + Contact us for more information +
+ + + [[ include ../partials/confirm-modal ]] + [[ include ../projects/layouts-modal ]] + [[ include ../partials/sign-in ]] + [[ include ../partials/footer ]] + +
+ +[[ include ../partials/scripts ]] + diff --git a/views/about/howto.ejs b/views/about/howto.ejs index 5278a40..914c3b3 100644 --- a/views/about/howto.ejs +++ b/views/about/howto.ejs @@ -1,7 +1,7 @@ - vvalls + How to Use VValls [[ include ../partials/meta ]] diff --git a/views/builder.ejs b/views/builder.ejs index afb8c66..0ba4238 100644 --- a/views/builder.ejs +++ b/views/builder.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/docs.ejs b/views/docs.ejs index b3ead82..a1f081f 100644 --- a/views/docs.ejs +++ b/views/docs.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/editor.ejs b/views/editor.ejs index 656615c..74e4d6d 100755 --- a/views/editor.ejs +++ b/views/editor.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/home.ejs b/views/home.ejs index 36fc2fc..ffb0976 100755 --- a/views/home.ejs +++ b/views/home.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/modal.ejs b/views/modal.ejs index 7ca869c..732953d 100644 --- a/views/modal.ejs +++ b/views/modal.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/profile.ejs b/views/profile.ejs index a62652c..88af6b0 100644 --- a/views/profile.ejs +++ b/views/profile.ejs @@ -1,7 +1,7 @@ - vvalls + VValls | [[- profile.displayName ]] [[ include partials/meta ]] diff --git a/views/reader.ejs b/views/reader.ejs index 6c9856a..7035356 100644 --- a/views/reader.ejs +++ b/views/reader.ejs @@ -1,7 +1,7 @@ - vvalls + VValls [[ include partials/meta ]] diff --git a/views/staff/_header.ejs b/views/staff/_header.ejs index 3bbf4f1..a73c12e 100644 --- a/views/staff/_header.ejs +++ b/views/staff/_header.ejs @@ -1,7 +1,7 @@ - vvalls | staff + VValls | staff [[ include ../partials/meta ]] -- cgit v1.2.3-70-g09d2 From 372b8eb7f2a34902c72f5a831404070b5bd761c1 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 9 Jan 2015 07:53:23 -0500 Subject: edit brochure --- server/lib/views/index.js | 20 ++++++++++++++++++-- views/about/brochure.ejs | 12 ++++++------ 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'server/lib/views/index.js') diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 5f9088b..2a8f921 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -4,6 +4,7 @@ var User = require('../schemas/User'), Project = require('../schemas/Project'), Documentation = require('../schemas/Documentation'), Collaborator = require('../schemas/Collaborator'), + Plan = require('../schemas/Plan'), config = require('../../../config'), marked = require('marked'), util = require('../util'), @@ -111,9 +112,11 @@ var views = module.exports = { res.render('about/' + name) return } - if (name == "brochure") { + if (name == "brochure" || name == "plans") { // TODO: fetch plans - res.render('about/' + name) + views_middleware.ensurePlans(req, res, function(){ + res.render('about/' + name) + }) return } if (name == "about" || name == "index") { @@ -224,6 +227,19 @@ var views = module.exports = { } var views_middleware = { + ensurePlans: function(req, res, next){ + Plan.find(function (err, plans) { + res.locals.plans = {} + plans.forEach(function(plan){ + res.locals.plans[ plan.slug ] = plan + "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price pro_layout_monthly_price pro_layout_yearly_price".split(" ").forEach(function(key){ + plan[key] = (plan[key]/100).toFixed(2)+"" + }) + }) + next() + }) + }, + fetchProjects: function (criteria, limit, offset, next) { limit = limit || 7 offset = offset || 0 diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs index d816dc4..4ce558a 100644 --- a/views/about/brochure.ejs +++ b/views/about/brochure.ejs @@ -19,7 +19,7 @@

[[- plans.free.name ]]

    -
  • One exhibition with pre-designed template floor plan +
  • [[- plans.free.stock_project_limit ]] exhibition with pre-designed template floor plan
@@ -27,10 +27,10 @@

[[- plans.premium.name ]]

  • $[[- plans.premium.monthly_price ]]/mo or $[[- plans.premium.yearly_price ]]/year -
  • [[- plans.premium.stock_layout_project_limit ]] exhibitions included with pre-designed template floor plans +
  • [[- plans.premium.stock_project_limit ]] exhibitions included with pre-designed template floor plans
  • Each new basic floor plan costs $[[- plans.premium.basic_layout_monthly_price ]]/mo or $[[- plans.premium.basic_layout_yearly_price ]]/year, minimum 3 months -
  • Each new basic floor plan can have up to [[- plans.premium.basic_layout_project_limit ]] exhibitions +
  • Each new basic floor plan can have up to [[- plans.premium.basic_project_limit ]] exhibitions
  • VValls logo appears when embedding an exhibition on a web page
@@ -39,10 +39,10 @@

[[- plans.pro.name ]]

  • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year -
  • Comes with [[- plans.premium.pro_layout_limit ]] pro floor plan and [[- plans.premium.pro_layout_project_limit ]] exhibitions +
  • Comes with [[- plans.premium.pro_layout_limit ]] pro floor plan and [[- plans.premium.pro_project_limit ]] exhibitions
  • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months -
  • Each new pro floor plan can have up to [[- plans.pro.pro_layout_project_limit ]] exhibitions +
  • Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions
  • Includes planning for 3D objects in the room
  • No VValls logo on embed
@@ -57,7 +57,7 @@
- Pro Floor plan: Trace an arbitrary floor plan. + Pro Floor plan: Trace an arbitrary floor plan from image.
-- cgit v1.2.3-70-g09d2 From 717e87b7422db8e1eda655fbf04e45fe5f877c9b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 20 Jan 2015 00:10:23 -0500 Subject: combining webhook stuff --- package.json | 1 + server/index.js | 3 -- server/lib/api/profile.js | 1 + server/lib/schemas/Subscription.js | 1 + server/lib/schemas/User.js | 4 +- server/lib/views/index.js | 1 - server/lib/views/subscription.js | 105 ------------------------------------- server/lib/webhook/config.js | 6 +++ server/lib/webhook/index.js | 88 +++++++++++++++++++++++++++++++ 9 files changed, 100 insertions(+), 110 deletions(-) delete mode 100644 server/lib/views/subscription.js create mode 100644 server/lib/webhook/config.js create mode 100644 server/lib/webhook/index.js (limited to 'server/lib/views/index.js') diff --git a/package.json b/package.json index 34e0c4c..8afb96e 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "mongoose-unique-validator": "~0.3.0", "monk": "~0.7.1", "multer": "~0.1.0", + "node-recurly": "^2.1.0", "node-restful": "~0.1.14", "passport": "~0.2.0", "passport-facebook": "~1.0.3", diff --git a/server/index.js b/server/index.js index 0f4941a..9a9323c 100644 --- a/server/index.js +++ b/server/index.js @@ -70,9 +70,6 @@ site.setup = function(){ app.all('*', middleware.ensureLocals); app.all('*', middleware.ensureIP); - // where should this live? - app.get('/subscribe/webhook', views.subscription.webhook); - server = http.createServer(app) server.listen(app.get('port'), function () { console.log('Express server listening on port ' + app.get('port')); diff --git a/server/lib/api/profile.js b/server/lib/api/profile.js index 996505f..d72a2c3 100644 --- a/server/lib/api/profile.js +++ b/server/lib/api/profile.js @@ -32,6 +32,7 @@ var profile = { delete data.old_password delete data.new_password delete data.isStaff + delete data.plan_level data.updated_at = new Date () if (req.files.avatar) { diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 8315009..7f2579b 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -15,6 +15,7 @@ var SubscriptionSchema = new mongoose.Schema({ plans: [{ tier: { type: String }, monthly: { type: Boolean }, + projects: [{ type: mongoose.Schema.ObjectId }], }], created_at: { type: Date, default: Date.now }, diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index 180a140..ae1d912 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -54,7 +54,9 @@ var UserSchema = new mongoose.Schema({ type: String, default: "", }, - + + plan_level: { type: Number, default: 0 }, + location: { type: String, default: "" }, photo: { type: String, default: "" }, bio: { type: String, default: "" }, diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 2a8f921..0ce0357 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -22,7 +22,6 @@ marked.setOptions({ var views = module.exports = { staff: require('./staff'), - subscription: require('./subscription'), editor_new: function (req, res) { if (! req.user) { diff --git a/server/lib/views/subscription.js b/server/lib/views/subscription.js deleted file mode 100644 index b9c79cb..0000000 --- a/server/lib/views/subscription.js +++ /dev/null @@ -1,105 +0,0 @@ -/* jshint node: true */ - -var User = require('../schemas/User'), - Subscription = require('../schemas/Subscription'), - config = require('../../../config'), - middleware = require('../middleware'), - util = require('../util'), - _ = require('lodash'), - moment = require('moment'), - xml2js = require('xml2js'); - -var parser = new xml2js.Parser(); -// fs.readFile('./foo.xml', function(err, data) { -// parser.parseString(data, function (err, result) { -// console.log(inspect(result, { colors: true, depth: Infinity })); -// }); -// }); - -var subscription = module.exports = { - - fields: [ - // accounts - "new_account_notification", - "canceled_account_notification", - "billing_info_updated_notification", - "reactivated_account_notification", - - // invoices - "new_invoice_notification", - "closed_invoice_notification", - "past_due_invoice_notification", - - // subscriptions - "new_subscription_notification", - "updated_subscription_notification", - "canceled_subscription_notification", - "expired_subscription_notification", - "renewed_subscription_notification", - - // payments - "successful_payment_notification", - "failed_payment_notification", - "successful_refund_notification", - "void_payment_notification", - ], - - middleware: { - }, - - callbacks: { - // accounts - new_account_notification: function(data){ - }, - canceled_account_notification: function(data){ - }, - billing_info_updated_notification: function(data){ - }, - reactivated_account_notification: function(data){ - }, - - // invoices - new_invoice_notification: function(data){ - }, - closed_invoice_notification: function(data){ - }, - past_due_invoice_notification: function(data){ - }, - - // subscriptions - new_subscription_notification: function(data){ - }, - updated_subscription_notification: function(data){ - }, - canceled_subscription_notification: function(data){ - }, - expired_subscription_notification: function(data){ - }, - renewed_subscription_notification: function(data){ - }, - - // payments - successful_payment_notification: function(data){ - }, - failed_payment_notification: function(data){ - }, - successful_refund_notification: function(data){ - }, - void_payment_notification: function(data){ - }, - }, - - // need a route for the webhook, - // then calls to get appropriate info from the recurly api - webhook: function(req, res){ - res.status(200).end() - parser.parseString(data, function (err, result) { - console.log(inspect(result, { colors: true, depth: Infinity })); - for (var i in data) { - if (subscription.callbacks[i]) { - subscription.callbacks[i](data) - } - } - }); - }, -} diff --git a/server/lib/webhook/config.js b/server/lib/webhook/config.js new file mode 100644 index 0000000..ecafeb3 --- /dev/null +++ b/server/lib/webhook/config.js @@ -0,0 +1,6 @@ +module.exports = { + API_KEY: require('process').env['VVALLS_RECURLY_SECRET'], + SUBDOMAIN: 'vvalls', + ENVIRONMENT: 'sandbox', + DEBUG: true, +}; diff --git a/server/lib/webhook/index.js b/server/lib/webhook/index.js new file mode 100644 index 0000000..c4b4b76 --- /dev/null +++ b/server/lib/webhook/index.js @@ -0,0 +1,88 @@ +// // where should this live? +// app.get('/subscribe/webhook', views.subscription.webhook); + +/* jshint node: true */ + +var User = require('../schemas/User'), + Subscription = require('../schemas/Subscription'), + config = require('../../../config'), + middleware = require('../middleware'), + util = require('../util'), + _ = require('lodash'), + moment = require('moment'), + xml2js = require('xml2js'), + Recurly = require('node-recurly'), + recurly = new Recurly(require('./config')); + +var parser = new xml2js.Parser(); +// fs.readFile('./foo.xml', function(err, data) { +// parser.parseString(data, function (err, result) { +// console.log(inspect(result, { colors: true, depth: Infinity })); +// }); +// }); + +/* +app.use(express.basicAuth(function(user, pass, callback) { + var result = (user === 'testUser' && pass === 'testPass'); + callback(null, result); +})); +*/ + +var subscription = module.exports = { + + callbacks: { + // accounts + new_account_notification: function(data){ + }, + canceled_account_notification: function(data){ + }, + billing_info_updated_notification: function(data){ + }, + reactivated_account_notification: function(data){ + }, + + // invoices + new_invoice_notification: function(data){ + }, + closed_invoice_notification: function(data){ + }, + past_due_invoice_notification: function(data){ + }, + + // subscriptions + new_subscription_notification: function(data){ + }, + updated_subscription_notification: function(data){ + }, + canceled_subscription_notification: function(data){ + }, + expired_subscription_notification: function(data){ + }, + renewed_subscription_notification: function(data){ + }, + + // payments + successful_payment_notification: function(data){ + }, + failed_payment_notification: function(data){ + }, + successful_refund_notification: function(data){ + }, + void_payment_notification: function(data){ + }, + }, + + // need a route for the webhook, + // then calls to get appropriate info from the recurly api + webhook: function(req, res){ + res.status(200).end() + parser.parseString(data, function (err, result) { + console.log(inspect(result, { colors: true, depth: Infinity })); + for (var i in data) { + if (subscription.callbacks[i]) { + subscription.callbacks[i](data[i]) + } + } + }); + }, +} -- cgit v1.2.3-70-g09d2 From d86d15c60c06843f8f22cdcf5b809c3a48e6a628 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 17:05:15 -0500 Subject: plans partial, min on number fields --- .../javascripts/ui/site/EditSubscriptionModal.js | 32 +++--- public/assets/stylesheets/app.css | 60 ++++++++++- server/index.js | 2 + server/lib/api/subscription.js | 10 +- server/lib/views/index.js | 9 ++ views/about/brochure.ejs | 113 +-------------------- views/partials/edit-subscription.ejs | 17 ++-- views/staff/plans/_form.ejs | 24 ++--- 8 files changed, 114 insertions(+), 153 deletions(-) (limited to 'server/lib/views/index.js') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 8952e42..d5eb9ac 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -47,22 +47,28 @@ var EditSubscriptionModal = ModalFormView.extend({ basic: 1, pro: 2, }, + + sync: function(){ + $.put(this.syncAction, this.didLoad.bind(this)) + }, loaded: false, load: function(){ this.reset() if (this.loaded) { return this.show() } - $.get(this.action, function(data){ - this.loaded = true - if (data.subscriber) { - this.subscriber = data.subscription - this.plans = data.plans - } - else if (data.error) { - // ...no subscription found - } - return this.show() - }.bind(this)) + $.get(this.action, this.didLoad.bind(this)) + }, + didLoad: function(data){ + this.loaded = true + this.plans = data.plans + if (data.subscription) { + this.subscriber = data.subscription + } + else if (data.error) { + // ...no subscription found + this.subscriber = null + } + return this.show() }, show: function(){ @@ -122,20 +128,18 @@ var EditSubscriptionModal = ModalFormView.extend({ type: "put", data: { _csrf: this.$csrf.val() }, success: function(data){ - window.location.href = "/profile" } }) }, destroy: function(){ - var msg = "Are you sure you want to cancel your subscription " + sanitize(this.$name.val()) + "?" + var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ $.ajax({ url: this.destroyAction, type: "delete", data: { _csrf: this.$csrf.val() }, success: function(data){ - window.location.href = "/profile" } }) }.bind(this)) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 0ce2c5e..5d7199c 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -156,7 +156,7 @@ a{ display: none; border-right:0px!important; } -.editProfile, .profileLink { +.profileLink { border-right:0px!important; } .editing #help-button { @@ -849,6 +849,7 @@ iframe.embed { } + .projectList.about.gopro { padding:6% 0; } @@ -900,6 +901,57 @@ iframe.embed { background:black; color:white; } + +/* PLANS BROCHURE */ +/* nb these styles should be fixed for narrower screens/mobile layout */ +.about_plan { + width: 28vw; + margin: 2vw; + float: left; + min-height: 28vw; + position: relative; +} +.about_plan button { + position: absolute; + bottom: 5%; + left: 5%; + width: 90%; +} +.about_custom { + clear: both; + width: 76vw; + margin: 2vw 10vw; +} +.planbox { + padding: 2vw; + border: 1px solid #ddd; + background: white; + border-radius: 25px; + font-size: 15px; + line-height: 23px; + text-align: center; +} +.planbox h3 { + text-align: center; + margin-bottom: 10px; +} +.about_plan ul { + margin-bottom: 60px; +} +.planbox li { + list-style-type: none; + margin-bottom: 5px; +} +.planbox.miscbox { + border: 0; + background: #f8f8f8; +} +.about_custom a { + border-bottom: 1px solid; +} + +/* LAYOUTS MODAL */ + .templates { overflow: auto; max-height: 100%; @@ -918,8 +970,8 @@ iframe.embed { } .templates::-webkit-scrollbar-thumb { -background-color: white; -border-left: 1px solid black; + background-color: white; + border-left: 1px solid black; } .templates::-webkit-scrollbar-track { @@ -990,6 +1042,8 @@ border-left: 1px solid black; float:right; } +/* MX SCENE STUFF */ + .mx-scene { position:fixed; top:0; diff --git a/server/index.js b/server/index.js index 2f6cb2d..fa7044b 100644 --- a/server/index.js +++ b/server/index.js @@ -156,6 +156,8 @@ site.route = function () { app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) + app.get('/partials/plans', views.partials.plans) + app.get('/test/*', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal) views.staff.route(app) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 9478d78..b7b3434 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -84,7 +84,10 @@ var subscription = module.exports = { subscriber.save(function(){ user.save(function(){ - res.render(subscriber) + res.render({ + subscription: req.subscription, + plans: res.locals.plans + }) }) }) }) @@ -98,7 +101,10 @@ var subscription = module.exports = { }) } else { - res.json({ error: "no subscription" }) + res.json({ + error: "no subscription", + plans: res.locals.plans, + }) } }, diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 0ce0357..89167f7 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -104,6 +104,15 @@ var views = module.exports = { }) }, + partials: { + plans: function (req, res){ + views_middleware.ensurePlans(req, res, function(){ + console.log("<<<<
-
-

[[- plans.free.name ]]

-
    -
  • [[- plans.free.stock_project_limit ]] exhibition with pre-designed template floor plan -
-
- -
-

[[- plans.basic.name ]]

-
    -
  • $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year -
  • Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions -
  • Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo - or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months -
  • Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions -
  • VValls logo appears when embedding an exhibition on a web page -
  • - [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level) { ]] - - [[ } else if (user.plan_level == plan.level) { ]] - Current Level - [[ } ]] -
-
- -
-

[[- plans.pro.name ]]

-
    -
  • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year -
  • Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions -
  • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo - or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months -
  • Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions -
  • Includes planning for 3D objects in the room -
  • No VValls logo on embed -
  • - [[ if (! logged_in) { ]] - - [[ } else if (! user.plan_level) { ]] - - [[ } else if (user.plan_level == plan.level) { ]] - Current Level - [[ } else if (user.plan_level < plan.level) { ]] - - [[ } ]] -
-
- -
-
    -
  • Buying any extra floor plan unlocks collaboration. Invite an artist or curator to work on the exhibition with you. -
  • Basic Floor plan: Rectangle-based design of any dimension. -
  • Pro Floor plan: Trace an arbitrary floor plan from image. -
-
- -
-

Want Something Custom?

-
  • We offer customized white-label options for business and educational uses. -
  • Contact us for more information. -
  • + [[ include _plans ]] - [[ include ../partials/confirm-modal ]] [[ include ../projects/layouts-modal ]] [[ include ../partials/sign-in ]] @@ -91,51 +28,3 @@ [[ include ../partials/scripts ]] - \ No newline at end of file diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index bb7cc27..2f6e4c1 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -7,15 +7,14 @@
  • Edit Subscription

  • -
    - You are currently using the free plan. For access to all of Vvalls features, +
  • + You are currently using the free version of Vvalls. For access to all of Vvalls features, consider upgrading to a paid plan. -

    - View the Plans -

  • - + +
    +

    [[- plans.basic.name ]]

    +
      +
    • $[[- plans.basic.monthly_price ]]/mo or $[[- plans.basic.yearly_price ]]/year +
    • Comes with [[- plans.basic.basic_layout_limit ]] basic floor plan and [[- plans.basic.basic_project_limit ]] exhibitions +
    • Each new basic floor plan costs $[[- plans.basic.basic_layout_monthly_price ]]/mo + or $[[- plans.basic.basic_layout_yearly_price ]]/year, minimum 3 months +
    • Each new floor plan can have up to [[- plans.basic.basic_project_limit ]] exhibitions +
    • VValls logo appears when embedding an exhibition on a web page +
    • + [[ if (! logged_in) { ]] + + [[ } else if (! user.plan_level) { ]] + + [[ } else if (user.plan_level == plan.level) { ]] + Current Level + [[ } ]] +
    +
    + +
    +

    [[- plans.pro.name ]]

    +
      +
    • $[[- plans.pro.monthly_price ]]/mo or $[[- plans.pro.yearly_price ]]/year +
    • Comes with [[- plans.pro.pro_layout_limit ]] pro floor plan and [[- plans.pro.pro_project_limit ]] exhibitions +
    • Each new pro floor plan costs $[[- plans.pro.pro_layout_monthly_price ]]/mo + or $[[- plans.pro.pro_layout_yearly_price ]]/year, minimum 3 months +
    • Each new pro floor plan can have up to [[- plans.pro.pro_project_limit ]] exhibitions +
    • Includes planning for 3D objects in the room +
    • No VValls logo on embed +
    • + [[ if (! logged_in) { ]] + + [[ } else if (! user.plan_level) { ]] + + [[ } else if (user.plan_level == plan.level) { ]] + Current Level + [[ } else if (user.plan_level < plan.level) { ]] + + [[ } ]] +
    +
    + +
    +
      +
    • Buying any extra floor plan unlocks collaboration.
      Invite an artist or curator to work on the exhibition with you. +
    • Basic Floor plan: Rectangle-based design of any dimension. +
    • Pro Floor plan: Trace an arbitrary floor plan from image. +
    +
    + +
    +

    Want Something Custom?

    +
  • We offer customized white-label options for business and educational uses. +
  • Contact us for more information. +
  • diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 2f6e4c1..cc296f6 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -1,19 +1,19 @@
    X
    -
    +
    • Edit Subscription

    • -
    • +
    • You are currently using the free version of Vvalls. For access to all of Vvalls features, consider upgrading to a paid plan.

      - +
    • -
    • Your current plan level is diff --git a/views/staff/_users.ejs b/views/staff/_users.ejs index 053e289..46811b6 100644 --- a/views/staff/_users.ejs +++ b/views/staff/_users.ejs @@ -12,7 +12,8 @@
      [[- user.last_seen ]] -- cgit v1.2.3-70-g09d2 From 03842d65cc018f9a718b2408d19e978f3d08e042 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 2 Feb 2015 13:23:51 -0500 Subject: sanity --- server/lib/views/index.js | 2 +- server/lib/webhook/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'server/lib/views/index.js') diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 9f244c8..be46cc6 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -107,7 +107,7 @@ var views = module.exports = { partials: { plans: function (req, res){ views_middleware.ensurePlans(req, res, function(){ - res.render('about/_plans') + res.render('about/_plans', { logged_in: res.locals.logged_in || false }) }) }, }, diff --git a/server/lib/webhook/index.js b/server/lib/webhook/index.js index 11419c2..798e4be 100644 --- a/server/lib/webhook/index.js +++ b/server/lib/webhook/index.js @@ -37,7 +37,7 @@ site.ready = function(){ console.log('Webhook server listening on port ' + app.get('port')); }); - app.get('/', function(req,res){ res.send('HI THERE') }) + app.get('/', function(req,res){ res.send('hello@vvalls.com') }) webhook.route(app) } -- cgit v1.2.3-70-g09d2 From 8ae88bc8540c0b2265748cb0df452c0370630289 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Jul 2015 14:53:38 -0400 Subject: show plans on homepage --- server/lib/views/index.js | 16 ++++++++++------ views/about/_plans.ejs | 6 +++--- views/home.ejs | 15 ++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'server/lib/views/index.js') diff --git a/server/lib/views/index.js b/server/lib/views/index.js index be46cc6..5241ddb 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -89,17 +89,21 @@ var views = module.exports = { }, home: function (req, res) { - views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ - res.render('home', { - projects: projects || [] + views_middleware.ensurePlans(req, res, function(err){ + views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ + res.render('home', { + projects: projects || [], + }) }) }) }, demoHome: function (req, res) { - views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ - res.render('home', { - projects: projects || [] + views_middleware.ensurePlans(req, res, function(err){ + views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ + res.render('home', { + projects: projects || [], + }) }) }) }, diff --git a/views/about/_plans.ejs b/views/about/_plans.ejs index af2a050..ba42e28 100644 --- a/views/about/_plans.ejs +++ b/views/about/_plans.ejs @@ -1,4 +1,3 @@ -
      +

      Want Something Custom?

    • We offer customized white-label options for business and educational uses. diff --git a/views/home.ejs b/views/home.ejs index b83e3e9..2bf5662 100755 --- a/views/home.ejs +++ b/views/home.ejs @@ -62,15 +62,12 @@ [[ include projects/list-projects ]] -
      - - -

      Ready To Go Pro?

      - Use VValls as part of your product, service, or marketing campaign. - We offer many types of customizations, including automation of layouts, more elaborate floor plans, enhanced video, interactivity, and other features. - Contact -
      -
      +

      Sign Up

      + +
      + [[ include about/_plans ]] +
      + [[ include partials/confirm-modal ]] [[ include projects/layouts-modal ]] [[ include partials/sign-in ]] -- cgit v1.2.3-70-g09d2 From 599b43df07f092b35d25e7adac11db3c3b3d9c76 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 17 Aug 2015 12:23:39 -0400 Subject: BlueprintEditor --- public/assets/javascripts/ui/_router.js | 7 +- .../javascripts/ui/blueprint/BlueprintEditor.js | 155 +++++++++++++++++++++ .../javascripts/ui/blueprint/BlueprintView.js | 18 +-- server/index.js | 3 + server/lib/views/index.js | 4 + views/blueprint.ejs | 1 + views/controls/blueprint/editor.ejs | 53 ------- views/controls/blueprint/scaler.ejs | 48 +++++++ views/partials/scripts.ejs | 1 + 9 files changed, 227 insertions(+), 63 deletions(-) create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintEditor.js create mode 100644 views/controls/blueprint/scaler.ejs (limited to 'server/lib/views/index.js') diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 857377c..177e86f 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -38,6 +38,9 @@ var SiteRouter = Router.extend({ "/layout": 'layoutPicker', "/layout/:name": 'layoutEditor', + "/blueprint": 'blueprintEditor', + "/blueprint/:name": 'blueprintEditor', + "/project": 'projectPicker', "/project/new": 'newProject', "/project/new/:layout": 'projectNewWithLayout', @@ -160,13 +163,13 @@ var SiteRouter = Router.extend({ this.readerView.load(name) }, - blueprintEditor: function(e){ + blueprintEditor: function(e, name){ environment.init = environment.minimal app.launch() if (app.unsupported) return this.blueprintView = app.controller = new BlueprintView () - this.blueprintView.load() + this.blueprintView.load(name) }, signup: function(e){ diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js new file mode 100644 index 0000000..c781495 --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -0,0 +1,155 @@ + +var wall_height = 180 +var shapes = new ShapeList +var last_point = new vec2 (0,0) + +var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ + + initialize: function(opt){ + this.parent = opt.parent + + map = new Map ({ + type: "ortho", + el: document.querySelector("#orthographic"), + width: window.innerWidth/2, + height: window.innerHeight, + zoom: -2, + zoom_min: -6.2, + zoom_max: 1, + }) + map.ui.add_tool("arrow", new ArrowTool) + map.ui.add_tool("polyline", new PolylineTool) + map.ui.add_tool("ortho-polyline", new OrthoPolylineTool) + map.ui.add_tool("eraser", new EraserTool) + map.ui.add_tool("position", new PositionTool) + map.ui.placing = false + +/* + $(window).resize(function(){ + scene.width = window.innerWidth/2 + scene.height = window.innerHeight + map.canvas.width = map.dimensions.a = window.innerWidth/2 + map.canvas.height = map.dimensions.b = window.innerHeight/2 + }) +*/ + + var PerspectiveToolbar = new Toolbar (".persp-hud") + PerspectiveToolbar.add("orbit-mode", function(){ + controls.toggle(true) + movements.lock() + }) + PerspectiveToolbar.add("keyboard-mode", function(){ + controls.toggle(false) + movements.unlock() + movements.gravity(true) + cam.rotationX = 0 + cam.rotationY = -cam.rotationY + cam.x = 0 + cam.y = viewHeight + 100 + cam.z = 0 + }) + + var OrthographicToolbar = new Toolbar (".ortho-hud") + OrthographicToolbar.add("arrow-mode", function(){ + map.ui.set_tool("arrow") + }) + OrthographicToolbar.add("polyline-mode", function(){ + map.ui.set_tool("polyline") + }) + OrthographicToolbar.add("ortho-polyline-mode", function(){ + map.ui.set_tool("ortho-polyline") + }) + OrthographicToolbar.add("eraser-mode", function(){ + map.ui.set_tool("eraser") + }) + OrthographicToolbar.pick("ortho-polyline-mode") + }, + + animate: function(t, dt){ + map.update(t) + + movements.update(dt) + controls.update() + scene.update() + + map.draw.ctx.save() + map.draw.translate() + + floorplan.draw(map.draw.ctx, true) + + map.draw.coords() + + if (shapes.workline) { + shapes.workline.draw(map.draw.ctx) + if (map.ui.placing && last_point) { + shapes.workline.draw_line( map.draw.ctx, last_point ) + } + } + + shapes.forEach(function(shape){ + shape.draw(map.draw.ctx) + }) + + map.draw.ctx.strokeStyle = "#f00"; + map.draw.x_at(0,0) + map.draw.mouse(map.ui.mouse.cursor) + map.draw.camera(scene.camera) + + map.draw.ctx.restore() + }, + +}) + +function build () { + scene = new MX.Scene().addTo("#perspective") + scene.camera.radius = 20 + + viewHeight = 100 + + scene.width = window.innerWidth/2 + scene.height = window.innerHeight + scene.perspective = window.innerHeight + + cam = scene.camera + movements = new MX.Movements(cam, viewHeight) + movements.init() + movements.lock() + movements.velocity(8) + app.on("move", function(pos){ + cam.x = pos.x + cam.y = pos.y + cam.z = pos.z + }) + + floorplan = new MX.Image({ + src: "https://s3.amazonaws.com/luckyplop/fbf4295da80f1f66c5e4a248f2ea3e1ce7a22c3d.jpg", + keepImage: true, + rotationX: -PI/2, + rotationY: PI, + }) + scene.add(floorplan) + + // recenter perspective view by rightclicking map + floorplan.el.addEventListener("contextmenu", function(e){ + e.preventDefault() + var offset = offsetFromPoint(e, this) + var x = (offset.left - 0.5) * floorplan.width * floorplan.scale + var z = (offset.top - 0.5) * floorplan.height * floorplan.scale + controls.opt.center.x = -x + controls.opt.center.y = 0 + controls.opt.center.z = -z + }, true) + + scene.update() + + controls = new MX.OrbitCamera({ + el: scene.el, + radius: 3000, + radiusRange: [ 10, 10000 ], + rotationX: PI/4, + rotationY: PI/2, + }) + controls.init() + + animate(0) +} diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index 6b204e5..0a06fda 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -1,7 +1,9 @@ var BlueprintView = View.extend({ el: "#blueprintView", - + + action: "/api/layout/", + events: { }, @@ -16,14 +18,14 @@ var BlueprintView = View.extend({ }, load: function(name){ -// if (! name || name == "new") { + if (! name || name == "new") { // this.ready({ isNew: true, _id: "new", name: "" }) -// return -// } -// -// name = sanitize(name) -// -// $.get(this.action + name, this.ready.bind(this)) + return + } + + name = sanitize(name) + + $.get(this.action + name, this.ready.bind(this)) }, ready: function(data){ diff --git a/server/index.js b/server/index.js index 0028888..078db8e 100644 --- a/server/index.js +++ b/server/index.js @@ -127,6 +127,9 @@ site.route = function () { app.get('/layout', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal) app.get('/layout/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.builder) + app.get('/blueprint', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint) + app.get('/blueprint/:name', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.blueprint) + app.get('/join/:nonce', middleware.ensureAuthenticated, api.collaborator.join) app.get('/api/collaborator/:slug/index', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.index) app.post('/api/collaborator/:slug/create', middleware.ensureAuthenticated, middleware.ensureProject, api.collaborator.create) diff --git a/server/lib/views/index.js b/server/lib/views/index.js index 5241ddb..523f628 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -84,6 +84,10 @@ var views = module.exports = { res.render('builder') }, + blueprint: function (req, res) { + res.render('blueprint') + }, + modal: function (req, res) { res.render('modal'); }, diff --git a/views/blueprint.ejs b/views/blueprint.ejs index 371d66f..7e13318 100644 --- a/views/blueprint.ejs +++ b/views/blueprint.ejs @@ -16,6 +16,7 @@ [[ include controls/builder/toolbar ]] [[ include controls/builder/settings ]] [[ include controls/blueprint/editor ]] + [[ include controls/blueprint/scaler ]]
    • diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index e18f501..5334f85 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -1,8 +1,4 @@