From be603d871e7a0117698177405f98cd07be7d12ed Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 10 Oct 2014 18:50:32 -0400 Subject: load more --- server/index.js | 1 + 1 file changed, 1 insertion(+) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index f6636dd..8f66418 100644 --- a/server/index.js +++ b/server/index.js @@ -133,6 +133,7 @@ site.route = function () { app.delete('/api/layout/destroy', middleware.ensureAuthenticated, middleware.ensureIsStaff, api.layouts.destroy) app.get('/api/project', middleware.ensureAuthenticated, api.projects.index) + app.get('/api/project/paginate', views.projectsPaginate) app.get('/api/project/:slug', api.projects.show) app.get('/api/rooms/:slug', api.rooms.show) app.post('/api/project/new', middleware.ensureAuthenticated, api.projects.create) -- cgit v1.2.3-70-g09d2 From e92acfd9a8b7b60544c8b85ad856273c732a1935 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Oct 2014 12:06:25 -0400 Subject: vvalls.com/home for testing --- public/assets/javascripts/ui/_router.js | 1 + public/assets/javascripts/ui/editor/WallpaperPicker.js | 2 +- server/index.js | 1 + server/lib/views/index.js | 8 ++++++++ 4 files changed, 11 insertions(+), 1 deletion(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index bda0960..c7b625a 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -46,6 +46,7 @@ var SiteRouter = Router.extend({ mobileRoutes: { "/": 'home', + "/home": 'home', "/profile": 'profile', "/project/:name": 'projectViewer', }, diff --git a/public/assets/javascripts/ui/editor/WallpaperPicker.js b/public/assets/javascripts/ui/editor/WallpaperPicker.js index d7d666c..c383489 100644 --- a/public/assets/javascripts/ui/editor/WallpaperPicker.js +++ b/public/assets/javascripts/ui/editor/WallpaperPicker.js @@ -54,7 +54,7 @@ var WallpaperPicker = UploadView.extend({ // toggle the class that makes the cursor a paintbucket // $("body").removeClass("pastePaper") }, - + load: function(){ $.get("/api/media/user", { tag: this.mediaTag }, this.populate.bind(this)) }, diff --git a/server/index.js b/server/index.js index 8f66418..90b724c 100644 --- a/server/index.js +++ b/server/index.js @@ -79,6 +79,7 @@ site.setup = function(){ site.route = function () { app.get('/', views.home); + app.get('/home', views.demoHome); app.get('/login', views.modal); app.get('/logout', auth.logout); app.get('/signup', views.modal); diff --git a/server/lib/views/index.js b/server/lib/views/index.js index eacff1f..5768ace 100644 --- a/server/lib/views/index.js +++ b/server/lib/views/index.js @@ -90,6 +90,14 @@ var views = module.exports = { }) }, + demoHome: function (req, res) { + views_middleware.fetchProjects({ featured: true }, null, null, function(err, projects){ + res.render('home', { + projects: projects || [] + }) + }) + }, + docs: function (req, res){ var name = req.params.name || "index" -- cgit v1.2.3-70-g09d2 From 94f19d836cfc80cd9d4fcfed17c1e2f025002994 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 7 Nov 2014 18:29:00 -0500 Subject: alias login -> signin --- public/assets/javascripts/ui/_router.js | 2 ++ server/index.js | 2 ++ server/lib/auth/index.js | 3 +-- views/partials/header.ejs | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 7337357..4219a28 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -20,6 +20,7 @@ var SiteRouter = Router.extend({ "/": 'home', "/home": 'home', "/login": 'signin', + "/signin": 'signin', "/signup": 'signup', "/auth/usernameTaken": 'usernameTaken', @@ -47,6 +48,7 @@ var SiteRouter = Router.extend({ "/": 'home', "/home": 'home', "/login": 'signin', + "/signin": 'signin', "/signup": 'signup', "/auth/usernameTaken": 'usernameTaken', "/auth/password": 'passwordReset', diff --git a/server/index.js b/server/index.js index 90b724c..c2b3421 100644 --- a/server/index.js +++ b/server/index.js @@ -82,6 +82,8 @@ site.route = function () { app.get('/home', views.demoHome); app.get('/login', views.modal); app.get('/logout', auth.logout); + app.get('/signin', views.modal); + app.get('/signout', auth.logout); app.get('/signup', views.modal); app.post('/auth/signin', auth.loggedInLocal); app.post('/auth/signup', auth.signup); diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js index c2275ff..0c46105 100644 --- a/server/lib/auth/index.js +++ b/server/lib/auth/index.js @@ -30,14 +30,13 @@ var auth = { callbackURL: 'http://' + config.host + '/auth/twitter/callback' }, auth.insertTwitterUser)); - /* passport.use(new FacebookStrategy({ clientID: process.env.VVALLS_FACEBOOK_KEY || '719828821410310', clientSecret: process.env.VVALLS_FACEBOOK_SECRET || 'f9aba78e08f37f621eadb88b1409d48c', callbackURL: 'http://' + config.host + '/auth/facebook/callback', enableProof: false, }, auth.insertFacebookUser)); - */ + auth.mail.init() }, diff --git a/views/partials/header.ejs b/views/partials/header.ejs index ea579cc..ce5bab9 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -74,7 +74,7 @@ [[ } else { ]] - + [[ } ]] \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 2017cf240fc1576e81a6fb9a53439f9fe76653e5 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 13 Nov 2014 14:29:25 -0500 Subject: minified js via grunt --- .gitignore | 3 + Gruntfile.js | 163 +++++++++++++++++++++++++++++++++++++++++++++ server/index.js | 1 + views/partials/scripts.ejs | 5 +- 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 Gruntfile.js (limited to 'server/index.js') diff --git a/.gitignore b/.gitignore index c0f4c0c..50f54f1 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ tmp/ config.json +app.concat.js +app.min.js + diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..bba8f22 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,163 @@ +module.exports = function(grunt) { + + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + concat: { + options: { + separator: "\n;\n" + }, + js: { + src: [ + "public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js", + "public/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js", + "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js", + "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js", + "public/assets/javascripts/vendor/bower_components/prefixfree/prefixfree.min.js", + "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js", + "public/assets/javascripts/vendor/tube.js", + "public/assets/javascripts/vendor/loader.js", + "public/assets/javascripts/vendor/polyfill.js", + "public/assets/javascripts/vendor/chardinjs.min.js", + "public/assets/javascripts/vendor/sha1.js", + "public/assets/javascripts/vendor/dataUriToBlob.js", + "public/assets/javascripts/vendor/froogaloop.js", + "public/assets/javascripts/util.js", + + "public/assets/javascripts/mx/mx.js", + "public/assets/javascripts/mx/extensions/mx.scene.js", + "public/assets/javascripts/mx/extensions/mx.movements.js", + "public/assets/javascripts/mx/extensions/mx.movementsMobile.js", + "public/assets/javascripts/mx/primitives/mx.image.js", + "public/assets/javascripts/mx/primitives/mx.text.js", + "public/assets/javascripts/mx/primitives/mx.video.js", + "public/assets/javascripts/mx/primitives/mx.youtube.js", + "public/assets/javascripts/mx/primitives/mx.vimeo.js", + + "public/assets/javascripts/rectangles/_env.js", + + "public/assets/javascripts/rectangles/util/constants.js", + "public/assets/javascripts/rectangles/util/colors.js", + "public/assets/javascripts/rectangles/util/coords.js", + "public/assets/javascripts/rectangles/util/debug.js", + "public/assets/javascripts/rectangles/util/keys.js", + "public/assets/javascripts/rectangles/util/measurement.js", + "public/assets/javascripts/rectangles/util/minotaur.js", + "public/assets/javascripts/rectangles/util/mouse.js", + "public/assets/javascripts/rectangles/util/permissions.js", + "public/assets/javascripts/rectangles/util/sort.js", + "public/assets/javascripts/rectangles/util/uid.js", + "public/assets/javascripts/rectangles/util/undostack.js", + "public/assets/javascripts/rectangles/util/wheel.js", + + "public/assets/javascripts/rectangles/models/vec2.js", + "public/assets/javascripts/rectangles/models/vec3.js", + "public/assets/javascripts/rectangles/models/rect.js", + "public/assets/javascripts/rectangles/models/surface.js", + "public/assets/javascripts/rectangles/models/tree.js", + "public/assets/javascripts/rectangles/models/room.js", + "public/assets/javascripts/rectangles/models/wall.js", + "public/assets/javascripts/rectangles/models/floor.js", + + "public/assets/javascripts/rectangles/engine/rooms/_rooms.js", + "public/assets/javascripts/rectangles/engine/rooms/_walls.js", + "public/assets/javascripts/rectangles/engine/rooms/builder.js", + "public/assets/javascripts/rectangles/engine/rooms/clipper.js", + "public/assets/javascripts/rectangles/engine/rooms/grouper.js", + "public/assets/javascripts/rectangles/engine/rooms/mover.js", + + "public/assets/javascripts/rectangles/engine/scenery/_scenery.js", + "public/assets/javascripts/rectangles/engine/scenery/move.js", + "public/assets/javascripts/rectangles/engine/scenery/resize.js", + "public/assets/javascripts/rectangles/engine/scenery/randomize.js", + "public/assets/javascripts/rectangles/engine/scenery/undo.js", + "public/assets/javascripts/rectangles/engine/scenery/types/_object.js", + "public/assets/javascripts/rectangles/engine/scenery/types/image.js", + "public/assets/javascripts/rectangles/engine/scenery/types/text.js", + "public/assets/javascripts/rectangles/engine/scenery/types/video.js", + + "public/assets/javascripts/rectangles/engine/map/_map.js", + "public/assets/javascripts/rectangles/engine/map/ui_editor.js", + "public/assets/javascripts/rectangles/engine/map/ui_minimap.js", + "public/assets/javascripts/rectangles/engine/map/draw.js", + + "public/assets/javascripts/ui/lib/View.js", + "public/assets/javascripts/ui/lib/Router.js", + "public/assets/javascripts/ui/lib/ModalView.js", + "public/assets/javascripts/ui/lib/FormView.js", + "public/assets/javascripts/ui/lib/UploadView.js", + "public/assets/javascripts/ui/lib/AlertModal.js", + "public/assets/javascripts/ui/lib/ConfirmModal.js", + "public/assets/javascripts/ui/lib/ErrorModal.js", + "public/assets/javascripts/ui/lib/Parser.js", + "public/assets/javascripts/ui/lib/LabColorPicker.js", + + "public/assets/javascripts/ui/site/SignInModal.js", + "public/assets/javascripts/ui/site/SignUpModal.js", + "public/assets/javascripts/ui/site/UsernameTaken.js", + "public/assets/javascripts/ui/site/PasswordForgot.js", + "public/assets/javascripts/ui/site/PasswordReset.js", + "public/assets/javascripts/ui/site/LayoutsModal.js", + "public/assets/javascripts/ui/site/EditProjectModal.js", + "public/assets/javascripts/ui/site/EditProfileModal.js", + "public/assets/javascripts/ui/site/DocumentModal.js", + + "public/assets/javascripts/ui/site/HomeView.js", + "public/assets/javascripts/ui/site/ProfileView.js", + "public/assets/javascripts/ui/site/ProjectList.js", + + "public/assets/javascripts/ui/builder/BuilderView.js", + "public/assets/javascripts/ui/builder/BuilderSettings.js", + "public/assets/javascripts/ui/builder/BuilderToolbar.js", + "public/assets/javascripts/ui/builder/BuilderInfo.js", + + "public/assets/javascripts/ui/editor/EditorView.js", + "public/assets/javascripts/ui/editor/EditorSettings.js", + "public/assets/javascripts/ui/editor/EditorToolbar.js", + "public/assets/javascripts/ui/editor/HelpCursor.js", + "public/assets/javascripts/ui/editor/ColorControl.js", + "public/assets/javascripts/ui/editor/Collaborators.js", + "public/assets/javascripts/ui/editor/MediaEditor.js", + "public/assets/javascripts/ui/editor/MediaUpload.js", + "public/assets/javascripts/ui/editor/MediaViewer.js", + "public/assets/javascripts/ui/editor/Presets.js", + "public/assets/javascripts/ui/editor/TextEditor.js", + "public/assets/javascripts/ui/editor/WallpaperPicker.js", + + "public/assets/javascripts/ui/reader/ReaderView.js", + "public/assets/javascripts/ui/reader/ShareView.js", + "public/assets/javascripts/ui/reader/EmbedView.js", + "public/assets/javascripts/ui/reader/MediaPlayer.js", + "public/assets/javascripts/ui/reader/Tracker.js", + + "public/assets/javascripts/ui/_router.js", + + "public/assets/javascripts/app.js", + "public/assets/javascripts/defaults.js", + ], + dest: 'public/assets/javascripts/app.concat.js', + } + }, + uglify: { + options: { + banner: '/* vvalls by okfoc.us 2014 */\n' + }, + js: { + src: 'public/assets/javascripts/app.concat.js', + dest: 'public/assets/javascripts/app.min.js', + } + }, + clean: { + release: ["public/assets/javascripts/app.concat.js"], + } + }); + + // Load tasks that we'll be using + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-clean'); + + // Default task(s). + grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']); + grunt.registerTask('default', ['js']); +}; + diff --git a/server/index.js b/server/index.js index c2b3421..4fbd8d1 100644 --- a/server/index.js +++ b/server/index.js @@ -62,6 +62,7 @@ site.setup = function(){ app.use(passport.session()); app.use(app.router); app.set('trust proxy', true) + app.set('env', config.env.production ? "production" : "development") app.get('env') === 'development' && app.use(express.errorHandler()); // Essential middleware diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 7bdb246..d5e8e5d 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -1,3 +1,6 @@ +[[ if (config.env.production) { ]] + +[[ } else { ]] @@ -124,6 +127,6 @@ +[[ } ]] - -- cgit v1.2.3-70-g09d2 From 74c1e0ca2b343eb9084a90e7a9490f58cb2c81d1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 24 Nov 2014 17:12:00 -0500 Subject: databaseHost --- config.json.example | 1 + server/index.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'server/index.js') diff --git a/config.json.example b/config.json.example index 90df381..6028021 100644 --- a/config.json.example +++ b/config.json.example @@ -3,6 +3,7 @@ "hostName": "lvh.me", "port": 3000, "socketPort": 1337, + "databaseHost": "lvh.me", "pageSize": 10, "env": { "development": 1 } } diff --git a/server/index.js b/server/index.js index 4fbd8d1..e817566 100644 --- a/server/index.js +++ b/server/index.js @@ -20,7 +20,7 @@ var http = require('http'), var app = express() var server -var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.hostName + '/vvalls') +var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.databaseHost + '/vvalls') // -- cgit v1.2.3-70-g09d2 From 668241bbbc5150f8d4f573be9a1b4c17c1d017b6 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 24 Nov 2014 17:29:02 -0500 Subject: cache x-forwarded-for ip address on session object --- server/index.js | 1 + server/lib/middleware.js | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index e817566..9a9323c 100644 --- a/server/index.js +++ b/server/index.js @@ -68,6 +68,7 @@ site.setup = function(){ // Essential middleware // app.all('*', middleware.enableCORS); app.all('*', middleware.ensureLocals); + app.all('*', middleware.ensureIP); server = http.createServer(app) server.listen(app.get('port'), function () { diff --git a/server/lib/middleware.js b/server/lib/middleware.js index 7b37658..ad0d228 100644 --- a/server/lib/middleware.js +++ b/server/lib/middleware.js @@ -33,6 +33,15 @@ var middleware = { } next(); }, + + ensureIP: function (req, res, next) { + if (req.ips) { + req.ip = req.session.ip = req.ips[0] + } + else { + req.ip = req.session.ip || "127.0.0.1" + } + }, ensureLocals: function (req, res, next) { res.locals.token = req.csrfToken(); -- cgit v1.2.3-70-g09d2 From dcfbf734436fad76f5ca2e1cecadf4051118d56f Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Mon, 12 Jan 2015 12:24:57 -0500 Subject: stubbing webhook --- server/index.js | 2 ++ server/lib/views/staff.js | 2 +- server/lib/views/subscription.js | 21 ++++++--------------- 3 files changed, 9 insertions(+), 16 deletions(-) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index 9a9323c..a14eaab 100644 --- a/server/index.js +++ b/server/index.js @@ -70,6 +70,8 @@ site.setup = function(){ app.all('*', middleware.ensureLocals); app.all('*', middleware.ensureIP); + 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/views/staff.js b/server/lib/views/staff.js index d4abf1f..74dd7cd 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -765,7 +765,7 @@ var staff = module.exports = { res.render('staff/subscriptions/index') }, show: function(req, res){ - res.render('staff/subscriptions /show') + res.render('staff/subscriptions/show') }, }, diff --git a/server/lib/views/subscription.js b/server/lib/views/subscription.js index ba54bb4..e29e40d 100644 --- a/server/lib/views/subscription.js +++ b/server/lib/views/subscription.js @@ -32,19 +32,10 @@ var subscription = module.exports = { return project }, }, - - route: function(app){ - app.get('/staff', - middleware.ensureAuthenticated, - middleware.ensureIsStaff, - - staff.middleware.ensureRecentUsers, - staff.middleware.ensureUsersCount, - staff.middleware.ensureProjectsCount, - staff.middleware.ensureMediaCount, - - staff.index - ); - }, - + + // need a route for the webhook, + // then calls to get appropriate info from the recurly api + webhook: function(req, res){ + res.status(200).end() + }, } -- cgit v1.2.3-70-g09d2 From 034f8343f2d194c2b1e3dbb20cfb8658e2795ce0 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 12 Jan 2015 18:38:42 -0500 Subject: parsing some xml for webhooks --- package.json | 37 +++++++++--------- server/index.js | 1 + server/lib/views/subscription.js | 81 +++++++++++++++++++++++++++++++++++----- 3 files changed, 92 insertions(+), 27 deletions(-) (limited to 'server/index.js') diff --git a/package.json b/package.json index adefb82..34e0c4c 100644 --- a/package.json +++ b/package.json @@ -6,32 +6,33 @@ "url": "git://github.com/okfocus/vvalls.git" }, "dependencies": { - "express": "~3.4.8", - "monk": "~0.7.1", - "socket.io": "~0.9.16", + "body-parser": "1.3.0", "connect-mongo": "~0.4.1", - "passport": "~0.2.0", - "passport-local": "~1.0.0", - "passport-twitter": "~1.0.2", - "passport-facebook": "~1.0.3", - "passport.socketio": "~3.0.1", - "node-restful": "~0.1.14", "ejs": "^0.8.8", - "useful-string": "0.0.1", + "emailjs": "~0.3.6", + "express": "~3.4.8", "express-subdomain-handler": "~0.1.0", "express-subdomains": "0.0.5", + "html-entities": "~1.0.10", + "intro.js": "^0.9.0", + "knox": "~0.8.10", "lodash": "~2.4.1", + "marked": "~0.3.2", + "moment": "~2.6.0", "mongoose": "~3.8.8", - "mongoose-unique-validator": "~0.3.0", "mongoose-lifecycle": "~1.0.0", - "knox": "~0.8.10", - "moment": "~2.6.0", - "html-entities": "~1.0.10", + "mongoose-unique-validator": "~0.3.0", + "monk": "~0.7.1", "multer": "~0.1.0", - "body-parser": "1.3.0", - "marked": "~0.3.2", - "emailjs": "~0.3.6", - "intro.js": "^0.9.0" + "node-restful": "~0.1.14", + "passport": "~0.2.0", + "passport-facebook": "~1.0.3", + "passport-local": "~1.0.0", + "passport-twitter": "~1.0.2", + "passport.socketio": "~3.0.1", + "socket.io": "~0.9.16", + "useful-string": "0.0.1", + "xml2js": "^0.4.4" }, "devDependencies": { "grunt": "~0.4.1", diff --git a/server/index.js b/server/index.js index a14eaab..0f4941a 100644 --- a/server/index.js +++ b/server/index.js @@ -70,6 +70,7 @@ 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) diff --git a/server/lib/views/subscription.js b/server/lib/views/subscription.js index e29e40d..251e217 100644 --- a/server/lib/views/subscription.js +++ b/server/lib/views/subscription.js @@ -6,7 +6,15 @@ var User = require('../schemas/User'), middleware = require('../middleware'), util = require('../util'), _ = require('lodash'), - moment = require('moment'); + 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 = { @@ -24,18 +32,73 @@ var subscription = module.exports = { middleware: { }, - helpers: { - project: function(project){ - project = project.toObject() - project.date = moment( project.updated_at || project.created_at ).format("M/DD/YYYY hh:mm a") - project.user = {} - return project - }, - }, + fields: [ + "new_account_notification", + "canceled_account_notification", + "billing_info_updated_notification", + "reactivated_account_notification", + "new_invoice_notification", + "closed_invoice_notification", + "past_due_invoice_notification", + "new_subscription_notification", + "updated_subscription_notification", + "canceled_subscription_notification", + "expired_subscription_notification", + "renewed_subscription_notification", + "successful_payment_notification", + "failed_payment_notification", + "successful_refund_notification", + "void_payment_notification", + ], + + 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 })); + }); }, } -- 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/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 e0debd761bc24cd42f4140d2b6cc32a4271fe975 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 23 Jan 2015 02:35:46 -0500 Subject: getting webhooks in order.. didnt need as many as i thought --- Procfile | 3 +- config.json.example | 1 + server/index.js | 2 +- server/lib/schemas/User.js | 2 + server/lib/webhook/config.js | 2 +- server/lib/webhook/index.js | 119 +++++++++++++----------------------------- server/lib/webhook/webhook.js | 118 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 161 insertions(+), 86 deletions(-) create mode 100644 server/lib/webhook/webhook.js (limited to 'server/index.js') diff --git a/Procfile b/Procfile index 983db91..bab08fb 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ -web: node server \ No newline at end of file +web: node server +webhook: node server/lib/webhook \ No newline at end of file diff --git a/config.json.example b/config.json.example index 6028021..b8c310c 100644 --- a/config.json.example +++ b/config.json.example @@ -3,6 +3,7 @@ "hostName": "lvh.me", "port": 3000, "socketPort": 1337, + "webhookPort": 5000, "databaseHost": "lvh.me", "pageSize": 10, "env": { "development": 1 } diff --git a/server/index.js b/server/index.js index 9a9323c..02fea3c 100644 --- a/server/index.js +++ b/server/index.js @@ -72,7 +72,7 @@ site.setup = function(){ server = http.createServer(app) server.listen(app.get('port'), function () { - console.log('Express server listening on port ' + app.get('port')); + console.log('Vvalls server listening on port ' + app.get('port')); }); // var io = websocket.listen(server) diff --git a/server/lib/schemas/User.js b/server/lib/schemas/User.js index 867939e..77de2d4 100644 --- a/server/lib/schemas/User.js +++ b/server/lib/schemas/User.js @@ -56,6 +56,8 @@ var UserSchema = new mongoose.Schema({ }, plan_level: { type: Number, default: 0 }, + plan_type: { type: String, default: "free" }, + last_charged: { type: Date, default: null }, subscription_id: { type: mongoose.Schema.ObjectId }, location: { type: String, default: "" }, diff --git a/server/lib/webhook/config.js b/server/lib/webhook/config.js index ecafeb3..3d7e1c5 100644 --- a/server/lib/webhook/config.js +++ b/server/lib/webhook/config.js @@ -1,5 +1,5 @@ module.exports = { - API_KEY: require('process').env['VVALLS_RECURLY_SECRET'], + API_KEY: 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 index ebbd01a..7dd68e6 100644 --- a/server/lib/webhook/index.js +++ b/server/lib/webhook/index.js @@ -1,89 +1,42 @@ -// // where should this live? -// app.get('/subscribe/webhook', views.subscription.webhook); +var config = require('../../../config.json'), + http = require('http'), + express = require('express'), + bodyParser = require('body-parser'), + mongoose = require('mongoose'); -/* jshint node: true */ +var http = require('http'), + express = require('express'), + bodyParser = require('body-parser'), + multer = require('multer'), + MongoStore = require('connect-mongo')(express), + passport = require('passport'), + path = require('path'), + mongoose = require('mongoose'); -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 app = express() +var server +var DATABASE_URI = process.env.MONGOLAB_URI || ('mongodb://' + config.databaseHost + '/vvalls') -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 site = {} -/* -app.use(express.basicAuth(function(user, pass, callback) { - var result = (user === 'testUser' && pass === 'testPass'); - callback(null, result); -})); -*/ +site.init = function(){ + mongoose.connect(DATABASE_URI, {}, site.ready); +} + +site.ready = function(){ + app.set('port', config.webhookPort); + app.use(bodyParser()); + app.use(express.query()); + app.set('env', config.env.production ? "production" : "development") + app.get('env') === 'development' && app.use(express.errorHandler()); -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]) - } - } - }); - }, + server = http.createServer(app) + server.listen(app.get('port'), function () { + console.log('Webhook server listening on port ' + app.get('port')); + }); + + app.get('/', function(req,res){ res.send('HI THERE') }) + app.get('/subscribe/webhook', require('./webhook').webhook); } + +site.init() diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js new file mode 100644 index 0000000..067af30 --- /dev/null +++ b/server/lib/webhook/webhook.js @@ -0,0 +1,118 @@ +// // where should this live? +// app.get('/subscribe/webhook', views.subscription.webhook); + +/* +app.use(express.basicAuth(function(user, pass, callback) { + var result = (user === 'testUser' && pass === 'testPass'); + callback(null, result); +})); +*/ + + +/* 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(); + +var subscription = module.exports = { + plan_level: { + free: 0, + basic: 1, + pro: 2, + }, + + callbacks: { + // accounts + new_account_notification: function(data){ + // fires on successful signup + // use the account_code to find the user, + }, + 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){ + var account = data.account + User.findOne({ _id: account.account_code }, function(err, user){ + if (err) return; + var subscription = data.subscription + + var plan = subscription.plan.plan_code.split("_") + var plan_type = plan[0] + var plan_period = plan[1] + + user.plan_type = plan_type + user.plan_level = subscription.plan_level[plan_type] + + // subscription.uuid + // subscription.subscription_add_ons[] + // subscription.subscription_add_ons[0].quantity + user.save(function(){ + }) + + }) + }, + 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){ + var account = data.account + User.findOne({ _id: account.account_code }, function(err, user){ + if (err) return; + user.last_charged = new Date(data.transaction.date) + user.save(function(){ + }) + }) + }, + 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 3059c3203d2cec4e2e745be8c21c6d3fbddb0c14 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Wed, 28 Jan 2015 01:39:28 -0500 Subject: rigging EditSubscriptionModal --- Gruntfile.js | 1 + config.json.example | 1 - public/assets/javascripts/ui/_router.js | 10 ++++++++++ server/index.js | 1 + server/lib/api/subscription.js | 19 ++++++++++++++++--- server/lib/webhook/webhook.js | 14 ++++++++++++++ views/about/brochure.ejs | 3 +++ views/partials/edit-subscription.ejs | 1 - views/partials/scripts.ejs | 1 + 9 files changed, 46 insertions(+), 5 deletions(-) (limited to 'server/index.js') diff --git a/Gruntfile.js b/Gruntfile.js index f62cc82..ed236c5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -99,6 +99,7 @@ module.exports = function(grunt) { "public/assets/javascripts/ui/site/LayoutsModal.js", "public/assets/javascripts/ui/site/EditProjectModal.js", "public/assets/javascripts/ui/site/EditProfileModal.js", + "public/assets/javascripts/ui/site/EditSubscriptionModal.js", "public/assets/javascripts/ui/site/DocumentModal.js", "public/assets/javascripts/ui/site/HomeView.js", diff --git a/config.json.example b/config.json.example index b8c310c..dc79edd 100644 --- a/config.json.example +++ b/config.json.example @@ -5,6 +5,5 @@ "socketPort": 1337, "webhookPort": 5000, "databaseHost": "lvh.me", - "pageSize": 10, "env": { "development": 1 } } diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index 3532428..9e7ce75 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -9,6 +9,7 @@ var SiteRouter = Router.extend({ "click [data-role='new-project-modal']": 'newProject', "click [data-role='edit-project-modal']": 'editProject', "click [data-role='edit-profile-modal']": 'editProfile', + "click [data-role='edit-subscription-modal']": 'editSubscription', "click [data-role='new-document-modal']": 'newDocument', "click [data-role='edit-document-modal']": 'editDocument', "click [data-role='destroy-document-modal']": 'destroyDocument', @@ -29,6 +30,7 @@ var SiteRouter = Router.extend({ "/profile": 'profile', "/profile/edit": 'editProfile', + "/profile/billing": 'editSubscription', "/profile/:name": 'profile', "/about/:name/edit": 'editDocument', "/about/new": 'newDocument', @@ -56,6 +58,7 @@ var SiteRouter = Router.extend({ "/profile": 'profile', "/profile/edit": 'editProfile', + "/profile/billing": 'editSubscription', "/profile/:name": 'profile', "/project/:name": 'projectViewer', @@ -69,6 +72,7 @@ var SiteRouter = Router.extend({ this.newProjectModal = new NewProjectModal() this.editProjectModal = new EditProjectModal() this.editProfileModal = new EditProfileModal() + this.editSubscriptionModal = new EditSubscriptionModal() this.passwordForgotModal = new PasswordForgot() this.documentModal = new DocumentModal() this.profileView = new ProfileView() @@ -195,6 +199,12 @@ var SiteRouter = Router.extend({ this.editProfileModal.load() }, + editSubscription: function(e){ + e && e.preventDefault() + window.history.pushState(null, document.title, "/profile/billing") + + this.editSubscriptionModal.load() + }, newDocument: function(e){ diff --git a/server/index.js b/server/index.js index 02fea3c..475054d 100644 --- a/server/index.js +++ b/server/index.js @@ -102,6 +102,7 @@ site.route = function () { app.get('/profile', views.profile) app.get('/profile/edit', views.profile) + app.get('/profile/billing', views.profile) app.get('/profile/:username', views.profile) app.get('/about', views.docs); diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index bd19127..83644cf 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -18,16 +18,29 @@ var subscription = module.exports = { }) }, */ - show: function(req,res){ + 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) + sync: function(req, res){ + // fetch req.user._id + }, + + show: function(req, res){ // fetch from recurly }, - update: function(req,res){ + update: function(req, res){ // update plan_type on recurly // update add_ons on recurly }, - destroy: function(req,res){ + destroy: function(req, res){ // destroy on recurly }, diff --git a/server/lib/webhook/webhook.js b/server/lib/webhook/webhook.js index e9a7925..4f23d0b 100644 --- a/server/lib/webhook/webhook.js +++ b/server/lib/webhook/webhook.js @@ -134,7 +134,21 @@ var subscribe = module.exports = { }); }, + list: function(req, res){ + recurly.subscriptions.listByAccount(req.params.id, function(data){ + if (data.data != 404) { + res.json(data) + return + } + else { + res.json(data) + return + } + }) + }, + route: function(app){ app.post('/subscribe/webhook', subscribe.handle); + app.get('/subscribe/list/:id', subscribe.list); }, } diff --git a/views/about/brochure.ejs b/views/about/brochure.ejs index 1c808f8..49b03db 100644 --- a/views/about/brochure.ejs +++ b/views/about/brochure.ejs @@ -123,6 +123,9 @@ text-align: center; margin-bottom: 10px; } +.about_plan ul { + margin-bottom: 60px; +} .planbox li { list-style-type: none; margin-bottom: 5px; diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 1f8db62..adc3f71 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -44,7 +44,6 @@ - [[ } ]] diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index fc94992..04bd945 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -95,6 +95,7 @@ + -- cgit v1.2.3-70-g09d2 From f55d634b7b24b6af0fb7dd017544a79672bb1bc7 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Wed, 28 Jan 2015 22:23:03 -0500 Subject: routez --- server/index.js | 5 +++++ server/lib/api/subscription.js | 10 +--------- 2 files changed, 6 insertions(+), 9 deletions(-) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index 475054d..53da448 100644 --- a/server/index.js +++ b/server/index.js @@ -151,6 +151,11 @@ site.route = function () { app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload) app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy) + app.get('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.sync) + app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.show) + app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.update) + app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.destroy) + 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 140bd12..e7cd8f4 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -26,14 +26,6 @@ var subscription = module.exports = { }, }, -/* - index: function(req, res){ - Project.find({ user_id: req.user._id }, function(err, docs){ - res.json(docs) - }) - }, -*/ - // synchronise an account with recurly.. // useful when testing locally (where webhooks cannot be received) sync: function(req, res){ @@ -128,7 +120,7 @@ var subscription = module.exports = { return res.json(subscriber) }) }, - + destroy: function(req, res){ if (! req.subscription ) { return res.json({ error: "no subscription" }) -- cgit v1.2.3-70-g09d2 From bc2b23459714fbdde6b990b3f9d574b3d7224f03 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Fri, 30 Jan 2015 01:53:32 -0500 Subject: subscription routage & middleware --- server/index.js | 8 ++++---- server/lib/api/subscription.js | 17 ++++++++++++++++- server/lib/schemas/Subscription.js | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index 53da448..2f6cb2d 100644 --- a/server/index.js +++ b/server/index.js @@ -151,10 +151,10 @@ site.route = function () { app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload) app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy) - app.get('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.sync) - app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.show) - app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.update) - app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.destroy) + app.get('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.sync) + app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) + 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('/test/*', middleware.ensureAuthenticated, middleware.ensureIsStaff, views.modal) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index e7cd8f4..9478d78 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -24,10 +24,17 @@ var subscription = module.exports = { next() }) }, + ensurePlans: function(req, res, next){ + Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) { + res.locals.plans = (plans || []) + next() + }) + }, }, // synchronise an account with recurly.. // useful when testing locally (where webhooks cannot be received) + // parses the XML from the subscription API into something usable sync: function(req, res){ var subscriber = req.subscription || new Subscription () var user = req.user @@ -84,7 +91,15 @@ var subscription = module.exports = { }, show: function(req, res){ - res.json(req.subscription || { error: "no subscription" }) + if (req.subscription) { + res.json({ + subscription: req.subscription, + plans: res.locals.plans + }) + } + else { + res.json({ error: "no subscription" }) + } }, update: function(req, res){ diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 24c5096..44455a9 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -18,7 +18,7 @@ var SubscriptionSchema = new mongoose.Schema({ history: [{ action: { type: String }, - plan_id: { type: String }, + data: { type: String }, created_at: { type: Date, default: Date.now }, }], -- 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/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 -

  • - -- cgit v1.2.3-70-g09d2 From 9e8364dd574c02c8a5605c3b09c0230a5476f9b1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 30 Jan 2015 18:30:37 -0500 Subject: sync working --- public/assets/javascripts/ui/site/EditSubscriptionModal.js | 1 + server/index.js | 2 +- server/lib/api/subscription.js | 9 +++++---- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index b38894d..28d699c 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -60,6 +60,7 @@ var EditSubscriptionModal = ModalView.extend({ }, didLoad: function(data){ this.loaded = true + console.log("didLoad", data) this.plans = data.plans if (data.subscription) { this.subscriber = data.subscription diff --git a/server/index.js b/server/index.js index 5c14d9d..9f28f59 100644 --- a/server/index.js +++ b/server/index.js @@ -153,7 +153,7 @@ site.route = function () { app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) - app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.sync) + app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync) app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) app.get('/partials/plans', views.partials.plans) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 4ec7709..0801204 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -41,8 +41,9 @@ var subscription = module.exports = { sync: function(req, res){ var subscriber = req.subscription || new Subscription () var user = req.user - recurly.subscriptions.listByAccount(req.user._id, function(data){ - if (data.description !== 200) { + recurly.subscriptions.listByAccount(req.user._id, function(recurlyRes){ + var data = recurlyRes.data + if (recurlyRes.description !== 200) { res.json({ error: "no account" }) return } @@ -87,8 +88,8 @@ var subscription = module.exports = { subscriber.save(function(){ user.save(function(){ - res.render({ - subscription: req.subscription, + res.json({ + subscription: subscriber, plans: res.locals.plans }) }) -- cgit v1.2.3-70-g09d2 From af230e59ec431c9b617b0caf94dc7c37bb5e81af Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 09:16:27 -0500 Subject: handle cancelled subscription --- .../javascripts/ui/site/EditSubscriptionModal.js | 5 +- server/index.js | 2 +- server/lib/api/subscription.js | 78 +++++++++++++--------- server/lib/schemas/Subscription.js | 2 +- 4 files changed, 51 insertions(+), 36 deletions(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 82f6903..7dd527a 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -61,7 +61,6 @@ var EditSubscriptionModal = ModalView.extend({ }, didLoad: function(data){ this.loaded = true - console.log("didLoad", data) this.plans = data.plans if (data.subscription) { this.subscriber = data.subscription @@ -163,11 +162,13 @@ var EditSubscriptionModal = ModalView.extend({ e.preventDefault() var msg = "Are you sure you want to cancel your subscription?" ConfirmModal.confirm(msg, function(){ + this.__super__.show.call(this) $.ajax({ url: this.destroyAction, type: "delete", - data: { _csrf: this.$csrf.val() }, + data: { _csrf: $("[name=_csrf]").val() }, success: function(data){ + window.location.href = "/" } }) }.bind(this)) diff --git a/server/index.js b/server/index.js index 9f28f59..3572675 100644 --- a/server/index.js +++ b/server/index.js @@ -154,7 +154,7 @@ site.route = function () { app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync) - app.delete('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) + app.delete('/api/subscription/destroy', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.destroy) app.get('/partials/plans', views.partials.plans) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 0801204..285ce8b 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -51,40 +51,51 @@ var subscription = module.exports = { res.json({ error: "account error" }) return } + if (subscriber.state != "active") { + user.plan_type = "free" + user.plan_level = plan_levels["free"] - 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] + return subscriber.remove(function(){ + user.save(function(){ + res.json({ error: "account cancelled" }) + }) + }) + } + else { + 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.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(){ @@ -156,6 +167,9 @@ var subscription = module.exports = { subscriber.remove(function(){ req.user.plan_code = 0 req.user.plan_type = "free" + req.user.save(function(){ + res.json({ status: "OK" }) + }) }) }) }, diff --git a/server/lib/schemas/Subscription.js b/server/lib/schemas/Subscription.js index 44455a9..355bbe2 100644 --- a/server/lib/schemas/Subscription.js +++ b/server/lib/schemas/Subscription.js @@ -12,7 +12,7 @@ var SubscriptionSchema = new mongoose.Schema({ plan_type: { type: String, default: "free" }, plan_period: { type: String, default: "monthly" }, - subscription_uuid: { type: String }, + uuid: { type: String }, basic_layouts: { type: Number, default: 0 }, pro_layouts: { type: Number, default: 0 }, -- cgit v1.2.3-70-g09d2 From ef52758ef0c27760a93ca861f1d17259dbc40fc4 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Sat, 31 Jan 2015 19:10:24 -0500 Subject: adding radio buttons etc --- .../javascripts/ui/site/EditSubscriptionModal.js | 31 +++++++++++++++++-- public/assets/stylesheets/app.css | 11 +++++-- server/index.js | 2 +- server/lib/api/subscription.js | 2 +- views/partials/edit-subscription.ejs | 35 +++++++++++++++++----- 5 files changed, 68 insertions(+), 13 deletions(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/site/EditSubscriptionModal.js b/public/assets/javascripts/ui/site/EditSubscriptionModal.js index 0f72995..619bff8 100644 --- a/public/assets/javascripts/ui/site/EditSubscriptionModal.js +++ b/public/assets/javascripts/ui/site/EditSubscriptionModal.js @@ -35,6 +35,11 @@ var EditSubscriptionModal = ModalView.extend({ this.$planCost = this.$("[data-role=planCost]") this.$planTotal = this.$("[data-role=planTotal]") + this.$basicPlanName = this.$("[data-role=basicPlanName]") + this.$proPlanName = this.$("[data-role=proPlanName]") + this.$basicPlanCost = this.$("[data-role=basicPlanCost]") + this.$proPlanCost = this.$("[data-role=proPlanCost]") + this.$basicLayoutCost = this.$("[data-role=basicLayoutCost]") this.$basicLayoutQuantity = this.$("[data-role=basicLayoutQuantity]") this.$basicLayoutTotal = this.$("[data-role=basicLayoutTotal]") @@ -43,8 +48,24 @@ var EditSubscriptionModal = ModalView.extend({ this.$proLayoutQuantity = this.$("[data-role=proLayoutQuantity]") this.$proLayoutTotal = this.$("[data-role=proLayoutTotal]") + this.$showLayoutsMenu = this.$("[data-role=showLayoutsMenu]") + this.$showPlanMenu = this.$("[data-role=showPlanMenu]") + + this.$layoutsMenu = this.$("[data-role=layoutsMenu]") + this.$planMenu = this.$("[data-role=planMenu]") + this.$closeMenu = this.$("[data-role=closeMenu]") + + this.$buyLayouts = this.$("[data-role=buyLayouts]") + + this.$changePlan = this.$("[data-role=changePlan]") + + this.$basicLayoutInput = this.$("[data-role=basicLayoutInput]") + this.$proLayoutInput = this.$("[data-role=proLayoutInput]") + this.$planRadio = this.$("[name=planRadio]") + this.$upgradeSubscription = this.$("[data-role=upgradeSubscription]") this.$cancelSubscription = this.$("[data-role=cancelSubscription]") + this.$gear = this.$(".gear") }, @@ -100,7 +121,7 @@ var EditSubscriptionModal = ModalView.extend({ var t = {} t.is_pro = plan.name == "pro" t.is_monthly = subscriber.plan_period == "monthly" - t.plan_price = t.is_monthly ? plan.monthly_price : plan.yearly_price + t.plan_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.yearly_price t.basic_layout_price = t.is_monthly ? plan.basic_layout_monthly_price : plan.basic_layout_yearly_price t.basic_layout_total = subscriber.basic_layouts * t.basic_layout_price t.pro_layout_price = t.is_monthly ? plan.pro_layout_monthly_price : plan.pro_layout_yearly_price @@ -113,12 +134,18 @@ var EditSubscriptionModal = ModalView.extend({ var subscriber = this.subscriber var plan = this.plans[ this.plan_levels[ subscriber.plan_type ] ] var totals = this.calculateTotals(subscriber, plan) + + this.$basicPlanName.html ( this.plans[1].name ) + this.$proPlanName.html ( this.plans[2].name ) + this.$basicPlanCost.toDollars ( totals.is_monthly ? this.plans[1].monthly_price : this.plans[2].yearly_price) + this.$proPlanCost.toDollars ( totals.is_monthly ? this.plans[2].monthly_price : this.plans[2].yearly_price) this.$planName.html ( plan.name ) this.$planCost.toDollars ( totals.plan_price ) this.$billingInterval.html ( totals.is_monthly ? "mo." : "yr." ) - this.$proLayoutRow.toggle ( totals.is_pro ) + this.$basicLayoutRow.toggle ( subscriber.basic_layouts > 0 ) + this.$proLayoutRow.toggle ( totals.is_pro && subscriber.pro_layouts > 0) this.$basicLayoutCost.toDollars ( totals.basic_layout_price ) this.$basicLayoutQuantity.html ( subscriber.basic_layouts ) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 082a2d4..4144b8b 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -987,6 +987,8 @@ iframe.embed { font-size: 1.9vw; padding: 0; } + +/* debug sync button */ .editSubscription .gear { position: absolute; top: 10px; @@ -1053,8 +1055,13 @@ iframe.embed { background: red; border-color: red; } - - +/* purchase mode */ +.paidPlan input[type=number] { display: none } +.paidPlan.editing input[type=number] { display: inline-block } +.paidPlan.editing input[type=number]+span { display: none } +form .paidPlan div { float: none; } +form .paidPlan label { float: none; font-size: 2vw; margin: 0 10px; } +.paidPlan .upgradeMenu div { padding: 5px 10px; } /* LAYOUTS MODAL */ diff --git a/server/index.js b/server/index.js index 3572675..8c8212f 100644 --- a/server/index.js +++ b/server/index.js @@ -72,7 +72,7 @@ site.setup = function(){ server = http.createServer(app) server.listen(app.get('port'), function () { - console.log('Vvalls server listening on port ' + app.get('port')); + console.log('VValls server listening on port ' + app.get('port')); }); // var io = websocket.listen(server) diff --git a/server/lib/api/subscription.js b/server/lib/api/subscription.js index 3a8403f..6f08e66 100644 --- a/server/lib/api/subscription.js +++ b/server/lib/api/subscription.js @@ -28,7 +28,7 @@ var subscription = module.exports = { }) }, ensurePlans: function(req, res, next){ - Plan.find({}).sort({ 'level': -1 }).exec(function (err, plans) { + Plan.find({}).sort({ 'level': 1 }).exec(function (err, plans) { res.locals.plans = (plans || []) next() }) diff --git a/views/partials/edit-subscription.ejs b/views/partials/edit-subscription.ejs index 69ec88d..fcb4b94 100644 --- a/views/partials/edit-subscription.ejs +++ b/views/partials/edit-subscription.ejs @@ -8,13 +8,13 @@

    Edit Subscription

  • - You are currently using the free version of Vvalls. 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.




  • -
  • +
  • Your current plan level is @@ -25,13 +25,13 @@ - + - + @@ -42,9 +42,30 @@
    Additional Basic layouts each $/ $/
    Additional Pro layouts @ $ ... $/
    $/
    - - - +
    + + + +
    +
    + + +
    +
    +

    Select desired plan:

    +
    + + + $/ +
    +
    + + + $/ +
    + + +
  • -- cgit v1.2.3-70-g09d2 From 78620c1451f78bdb470ed89c8a1e5c7a6bb10990 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 3 Feb 2015 13:07:42 -0500 Subject: support basicAuth --- config.json.example | 3 ++- server/index.js | 1 + server/lib/auth/index.js | 9 ++++++++- 3 files changed, 11 insertions(+), 2 deletions(-) (limited to 'server/index.js') diff --git a/config.json.example b/config.json.example index 7072d48..7221aa0 100644 --- a/config.json.example +++ b/config.json.example @@ -5,5 +5,6 @@ "socketPort": 1337, "webhookPort": 5000, "databaseHost": "lvh.me", - "env": { "development": 1 } + "env": { "development": 1 }, + "basicAuth": { "user": "foo", "pass": "bar" } } diff --git a/server/index.js b/server/index.js index 8c8212f..7bc3f7f 100644 --- a/server/index.js +++ b/server/index.js @@ -39,6 +39,7 @@ site.ready = function(){ site.setup = function(){ var SessionStore = new MongoStore({ mongoose_connection: mongoose.connection }) + auth.initBasicAuth(app) app.set('port', config.port); app.set('views', path.join(__dirname, '../views')); app.set('view engine', 'ejs'); diff --git a/server/lib/auth/index.js b/server/lib/auth/index.js index 199377d..8e20bcc 100644 --- a/server/lib/auth/index.js +++ b/server/lib/auth/index.js @@ -39,7 +39,14 @@ var auth = { auth.mail.init() }, - + initBasicAuth: function(app){ + if (config.basicAuth) { + app.use(express.basicAuth(function(user, pass) { + return user === config.basicAuth.user && + pass === config.basicAuth.pass + })) + } + }, initSockets: function (io, SessionStore) { io.set('authorization', passportSocketIo.authorize({ cookieParser: express.cookieParser, -- cgit v1.2.3-70-g09d2 From 7fd34f49fea785f11320eec412a95726cbcf7349 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 17:59:51 -0400 Subject: static build target --- .gitignore | 3 + Gruntfile.js | 130 +++++++++++++- public/assets/javascripts/ui/reader/MediaPlayer.js | 2 +- public/assets/javascripts/ui/reader/ReaderView.js | 12 +- public/assets/javascripts/ui/reader/_router.js | 16 ++ public/assets/test/static.html | 196 +++++++++++++++++++++ server/index.js | 4 + 7 files changed, 354 insertions(+), 9 deletions(-) create mode 100644 public/assets/javascripts/ui/reader/_router.js create mode 100644 public/assets/test/static.html (limited to 'server/index.js') diff --git a/.gitignore b/.gitignore index 50f54f1..14d6d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ config.json app.concat.js app.min.js +reader.concat.js +reader.min.js + diff --git a/Gruntfile.js b/Gruntfile.js index 93f13fe..a3ef359 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -147,7 +147,110 @@ module.exports = function(grunt) { "public/assets/javascripts/defaults.js", ], dest: 'public/assets/javascripts/app.concat.js', + }, + + // this builds a static version of the vvalls code, suitable for embedding + // in another website. see assets/test/static.html + 'static': { + src: [ + "public/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js", + "public/assets/javascripts/vendor/bower_components/lodash/lodash.min.js", + "public/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js", + "public/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js", + "public/assets/javascripts/vendor/bower_components/marked/lib/marked.js", + "public/assets/javascripts/vendor/bower_components/hidpi-canvas/dist/hidpi-canvas.js", + "public/assets/javascripts/vendor/tube.js", + "public/assets/javascripts/vendor/loader.js", + "public/assets/javascripts/vendor/polyfill.js", + "public/assets/javascripts/vendor/froogaloop.js", + "public/assets/javascripts/util.js", + + "public/assets/javascripts/mx/mx.js", + "public/assets/javascripts/mx/extensions/mx.scene.js", + "public/assets/javascripts/mx/extensions/mx.movements.js", + "public/assets/javascripts/mx/extensions/mx.movementsMobile.js", + "public/assets/javascripts/mx/primitives/mx.image.js", + "public/assets/javascripts/mx/primitives/mx.text.js", + "public/assets/javascripts/mx/primitives/mx.video.js", + "public/assets/javascripts/mx/primitives/mx.youtube.js", + "public/assets/javascripts/mx/primitives/mx.vimeo.js", + "public/assets/javascripts/mx/primitives/mx.soundcloud.js", + "public/assets/javascripts/mx/primitives/mx.grid.js", + + "public/assets/javascripts/rectangles/_env.js", + + "public/assets/javascripts/rectangles/util/constants.js", + "public/assets/javascripts/rectangles/util/colors.js", + "public/assets/javascripts/rectangles/util/coords.js", + "public/assets/javascripts/rectangles/util/debug.js", + "public/assets/javascripts/rectangles/util/keys.js", + "public/assets/javascripts/rectangles/util/measurement.js", + "public/assets/javascripts/rectangles/util/minotaur.js", + "public/assets/javascripts/rectangles/util/mouse.js", + "public/assets/javascripts/rectangles/util/permissions.js", + "public/assets/javascripts/rectangles/util/sort.js", + "public/assets/javascripts/rectangles/util/uid.js", + "public/assets/javascripts/rectangles/util/undostack.js", + "public/assets/javascripts/rectangles/util/wheel.js", + + "public/assets/javascripts/rectangles/models/vec2.js", + "public/assets/javascripts/rectangles/models/vec3.js", + "public/assets/javascripts/rectangles/models/rect.js", + "public/assets/javascripts/rectangles/models/surface.js", + "public/assets/javascripts/rectangles/models/tree.js", + "public/assets/javascripts/rectangles/models/room.js", + "public/assets/javascripts/rectangles/models/wall.js", + "public/assets/javascripts/rectangles/models/floor.js", + + "public/assets/javascripts/rectangles/engine/rooms/_rooms.js", + "public/assets/javascripts/rectangles/engine/rooms/_walls.js", + "public/assets/javascripts/rectangles/engine/rooms/builder.js", + "public/assets/javascripts/rectangles/engine/rooms/clipper.js", + "public/assets/javascripts/rectangles/engine/rooms/grouper.js", + "public/assets/javascripts/rectangles/engine/rooms/mover.js", + + "public/assets/javascripts/rectangles/engine/scenery/_scenery.js", + "public/assets/javascripts/rectangles/engine/scenery/move.js", + "public/assets/javascripts/rectangles/engine/scenery/resize.js", + "public/assets/javascripts/rectangles/engine/scenery/randomize.js", + "public/assets/javascripts/rectangles/engine/scenery/sound.js", + "public/assets/javascripts/rectangles/engine/scenery/undo.js", + "public/assets/javascripts/rectangles/engine/scenery/types/_object.js", + "public/assets/javascripts/rectangles/engine/scenery/types/image.js", + "public/assets/javascripts/rectangles/engine/scenery/types/text.js", + "public/assets/javascripts/rectangles/engine/scenery/types/video.js", + "public/assets/javascripts/rectangles/engine/scenery/types/audio.js", + + "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js", + "public/assets/javascripts/rectangles/engine/sculpture/move.js", + "public/assets/javascripts/rectangles/engine/sculpture/resize.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js", + "public/assets/javascripts/rectangles/engine/sculpture/types/image.js", + + "public/assets/javascripts/rectangles/engine/map/_map.js", + "public/assets/javascripts/rectangles/engine/map/ui_editor.js", + "public/assets/javascripts/rectangles/engine/map/ui_minimap.js", + "public/assets/javascripts/rectangles/engine/map/draw.js", + + "public/assets/javascripts/ui/lib/View.js", + "public/assets/javascripts/ui/lib/Router.js", + "public/assets/javascripts/ui/lib/ModalView.js", + + "public/assets/javascripts/ui/reader/ReaderView.js", + "public/assets/javascripts/ui/reader/ShareView.js", + "public/assets/javascripts/ui/reader/EmbedView.js", + "public/assets/javascripts/ui/reader/MediaPlayer.js", + "public/assets/javascripts/ui/reader/Tracker.js", + + "public/assets/javascripts/ui/reader/_router.js", + + "public/assets/javascripts/app.js", + "public/assets/javascripts/defaults.js", + ], + dest: 'public/assets/javascripts/reader.concat.js', } + + }, copy: { concat: { @@ -158,7 +261,15 @@ module.exports = function(grunt) { }, ] }, - }, + 'static': { + files: [ + { + src: 'public/assets/javascripts/static.concat.js', + dest: 'public/assets/javascripts/static.min.js', + }, + ] + }, + }, uglify: { options: { banner: '/* vvalls by okfocus 2015 */\n' @@ -166,10 +277,17 @@ module.exports = function(grunt) { js: { src: 'public/assets/javascripts/app.concat.js', dest: 'public/assets/javascripts/app.min.js', + }, + 'static': { + src: 'public/assets/javascripts/static.concat.js', + dest: 'public/assets/javascripts/static.min.js', } }, clean: { - release: ["public/assets/javascripts/app.concat.js"], + release: [ + "public/assets/javascripts/static.concat.js", + "public/assets/javascripts/app.concat.js", + ], } }); @@ -180,8 +298,10 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-clean'); // Default task(s). - grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']); - grunt.registerTask('merge', ['concat:js', 'copy:concat']); - grunt.registerTask('default', ['js']); + grunt.registerTask('js', ['concat:js', 'uglify:js', 'clean:release']); + grunt.registerTask('js-test', ['concat:js', 'copy:concat']); + grunt.registerTask('static', ['concat:static', 'uglify:static', 'clean:release']); + grunt.registerTask('static-test', ['concat:static', 'copy:static']); + grunt.registerTask('default', ['js']); }; diff --git a/public/assets/javascripts/ui/reader/MediaPlayer.js b/public/assets/javascripts/ui/reader/MediaPlayer.js index 8424d9c..8e65976 100644 --- a/public/assets/javascripts/ui/reader/MediaPlayer.js +++ b/public/assets/javascripts/ui/reader/MediaPlayer.js @@ -1,5 +1,5 @@ -var MediaPlayer = FormView.extend({ +var MediaPlayer = View.extend({ el: "#mediaPlayer", events: { diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index e3e27c3..55d2520 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -31,7 +31,12 @@ var ReaderView = View.extend({ this.tracker = new Tracker ({ mode: mode }) - $.get(this.projectAction + name, this.ready.bind(this)) + if ('vvalls_data' in window) { + this.ready(window.vvalls_data) + } + else { + $.get(this.projectAction + name, this.ready.bind(this)) + } }, getQS: function(){ @@ -85,9 +90,10 @@ var ReaderView = View.extend({ Walls.setColor[mode](colors[mode]) }) - editor.permissions.clear() + window.editor && editor.permissions.clear() - this.listen() + // disable until we start using spinning again + // this.listen() }, listen: function(){ diff --git a/public/assets/javascripts/ui/reader/_router.js b/public/assets/javascripts/ui/reader/_router.js new file mode 100644 index 0000000..a0e346a --- /dev/null +++ b/public/assets/javascripts/ui/reader/_router.js @@ -0,0 +1,16 @@ + +var SiteRouter = Router.extend({ + el: "body", + + initialize: function(){ + app.launch() + if (app.unsupported) return + + this.readerView = app.controller = new ReaderView() + this.readerView.load() + + $("body").removeClass("loading") + } + +}) + diff --git a/public/assets/test/static.html b/public/assets/test/static.html new file mode 100644 index 0000000..90871a5 --- /dev/null +++ b/public/assets/test/static.html @@ -0,0 +1,196 @@ + + + + VValls + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +

    + Leaves and such +
    + +
    + + asdf +

    + + + Last modified 4/20/2015 + + + + + Edit Room + +
    + +
    + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    + X + +
    +
    +
    +

    Embed VValls

    + +

    + This code generates an iframe which will embed this room in your website or blog. +

    + + + dimensions: x + + + + test +
    +
    +
    +
    + +
    + +
    + +
    +
    + + + + + + + + + + diff --git a/server/index.js b/server/index.js index 7bc3f7f..391385c 100644 --- a/server/index.js +++ b/server/index.js @@ -66,6 +66,10 @@ site.setup = function(){ app.set('env', config.env.production ? "production" : "development") app.get('env') === 'development' && app.use(express.errorHandler()); + if (config.env.production) { + app.set('json spaces', 0) + } + // Essential middleware // app.all('*', middleware.enableCORS); app.all('*', middleware.ensureLocals); -- cgit v1.2.3-70-g09d2 From aaaff2081b49069cef94f5b19165b2ded3601e82 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 23 Apr 2015 16:59:35 -0400 Subject: DISABLE basic auth for now --- server/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/index.js') diff --git a/server/index.js b/server/index.js index 391385c..4926a94 100644 --- a/server/index.js +++ b/server/index.js @@ -39,7 +39,7 @@ site.ready = function(){ site.setup = function(){ var SessionStore = new MongoStore({ mongoose_connection: mongoose.connection }) - auth.initBasicAuth(app) + // auth.initBasicAuth(app) app.set('port', config.port); app.set('views', path.join(__dirname, '../views')); app.set('view engine', 'ejs'); -- 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/index.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/index.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 f74635f1d28d3450d7c4ddb9869685dc20019f3a Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 12 Aug 2015 19:22:06 -0400 Subject: store blueprint scale on server --- .../javascripts/ui/blueprint/BlueprintScaler.js | 17 +++++++++++------ public/assets/javascripts/ui/lib/FormView.js | 2 +- server/index.js | 1 + server/lib/api/media.js | 16 ++++++++++++++++ views/controls/blueprint/editor.ejs | 20 +++++++++++--------- 5 files changed, 40 insertions(+), 16 deletions(-) (limited to 'server/index.js') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js index addf9a9..c393cfb 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -2,16 +2,17 @@ var BlueprintScaler = ModalFormView.extend({ el: ".blueprintScaler", - method: "/api/media/scale", + action: "/api/media/scale", events: { "change [name=blueprint-dimensions]": "changeDimensions", "change [name=blueprint-units]": "changeUnits", "click .uploadNewBlueprint": "showBlueprintUpload", - "click #saveBlueprint": "save", }, - initialize: function(){ + initialize: function(opt){ + this.parent = opt.parent + this.$blueprintMap = this.$("#blueprintMap") this.$blueprintDimensionsRapper = this.$("#blueprintDimensions") this.$dimensions = this.$("[name=blueprint-dimensions]") @@ -46,8 +47,10 @@ var BlueprintScaler = ModalFormView.extend({ pick: function(media){ this.media = media - if (!! media.scale) { + if (!! media.units) { this.parent.useFloorplan(media) + this.hide() + return } this.floorplan.load({ media: media, keepImage: true }) @@ -115,13 +118,14 @@ var BlueprintScaler = ModalFormView.extend({ if (this.lineTool.line.length !== 2) return 0 var line = this.lineTool.line return dist( line[0].a, line[0].b, line[1].a, line[1].b ) - } + }, validate: function(){ var val = this.$dimensions.unitVal() var errors = [] if (! this.lineLength()) { errors.push("no line") + this.$dimensions.val("") alert("Please click two corners of a wall and then specify how long it is in feet or meters.") } else if (val == 0) { @@ -144,7 +148,8 @@ var BlueprintScaler = ModalFormView.extend({ success: function(){ this.animating = false - this.parent.useFloorplan(media) + this.parent.useFloorplan(this.media) + this.hide() }, }) diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js index f5845e7..33effc8 100644 --- a/public/assets/javascripts/ui/lib/FormView.js +++ b/public/assets/javascripts/ui/lib/FormView.js @@ -63,7 +63,7 @@ var FormView = View.extend({ save: function(e, successCallback, errorCallback){ e && e.preventDefault() - this.$errors.hide().css("opacity", 0.0); + this.$errors && this.$errors.hide().css("opacity", 0.0); if (this.validate) { var errors = this.validate() diff --git a/server/index.js b/server/index.js index db9b051..0028888 100644 --- a/server/index.js +++ b/server/index.js @@ -156,6 +156,7 @@ site.route = function () { app.get('/api/media/user', middleware.ensureAuthenticated, api.media.user) app.post('/api/media/new', middleware.ensureAuthenticated, api.media.create) app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload) + app.post('/api/media/scale', middleware.ensureAuthenticated, api.media.scale) app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy) app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) diff --git a/server/lib/api/media.js b/server/lib/api/media.js index 85cbdd6..68e012c 100644 --- a/server/lib/api/media.js +++ b/server/lib/api/media.js @@ -65,6 +65,22 @@ var media = { } }, + scale: function(req, res){ + var _id = req.body._id + var data = util.cleanQuery(req.body) + if (! _id) { return res.json({ error: 404 }) } + Media.findOne({ _id: _id }, function(err, doc){ + if (! doc) { return res.json({ error: 404 }) } + if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) } + doc.scale = data.scale + doc.units = data.units + doc.save(function(err, rec){ + if (err || ! rec) { return res.json({ error: err }) } + res.json(rec) + }) + }) + }, + destroy: function(req, res){ var _id = util.sanitize(req.body._id) if (! _id || ! _id.length) { diff --git a/views/controls/blueprint/editor.ejs b/views/controls/blueprint/editor.ejs index 3e0c097..77c958a 100644 --- a/views/controls/blueprint/editor.ejs +++ b/views/controls/blueprint/editor.ejs @@ -98,15 +98,17 @@ body { You can also upload another blueprint.

    -
    - - - -
    - +
    +
    + + + +
    + +
    -- 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/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 @@