diff options
| author | Julie Lala <jules@okfoc.us> | 2015-01-09 06:43:31 -0500 |
|---|---|---|
| committer | Julie Lala <jules@okfoc.us> | 2015-01-09 06:43:31 -0500 |
| commit | 664099f91ae3ed2d667d331b19c2e41dec60124c (patch) | |
| tree | 696d53c2097c9f18f87d37ed19efd6c92f21c51f | |
| parent | 190a145cf1433fde570df1ac9784d4c5cea77d3d (diff) | |
fix up plans form
| -rwxr-xr-x | public/assets/stylesheets/app.css | 6 | ||||
| -rw-r--r-- | public/assets/stylesheets/staff.css | 16 | ||||
| -rw-r--r-- | server/lib/views/staff.js | 70 | ||||
| -rw-r--r-- | server/repl.js | 2 | ||||
| -rw-r--r-- | views/staff/_nav.ejs | 1 | ||||
| -rw-r--r-- | views/staff/index.ejs | 6 | ||||
| -rw-r--r-- | views/staff/plans/_form.ejs | 160 | ||||
| -rw-r--r-- | views/staff/plans/edit.ejs | 2 | ||||
| -rw-r--r-- | views/staff/plans/index.ejs | 11 | ||||
| -rw-r--r-- | views/staff/plans/new.ejs | 4 |
10 files changed, 186 insertions, 92 deletions
diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 0463e26..9e86ac3 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -2478,7 +2478,7 @@ form li { form label { float:left; } -form input[type="text"],form input[type="password"] { +form input[type="text"],form input[type="password"],form input[type="number"] { border: 1px solid; font-size: 20px; padding: 5px; @@ -3048,8 +3048,8 @@ a[data-role="forgot-password"] { form li { font-size: 16px; } - form input[type="text"], form input[type="password"] { - font-size: 15px; + form input[type="text"],form input[type="password"],form input[type="number"] { + font-size: 15px; } .page h1 { font-size: 26px; diff --git a/public/assets/stylesheets/staff.css b/public/assets/stylesheets/staff.css index de31571..e5cafa2 100644 --- a/public/assets/stylesheets/staff.css +++ b/public/assets/stylesheets/staff.css @@ -71,6 +71,22 @@ hr { color: #00f; border-bottom: 1px solid; } +.staff form { + max-width: none; + width: 600px; + padding: 20px; +} +.staff form label { + float: none; +} +.staff form p { + width: 350px; + margin: 5px 0; + color: #444; +} +.staff form div li { + width: 180px; +} #iframe-embed, #iframe-embed tr, #iframe-embed td { width: 79vw; } diff --git a/server/lib/views/staff.js b/server/lib/views/staff.js index ce676ed..6639137 100644 --- a/server/lib/views/staff.js +++ b/server/lib/views/staff.js @@ -18,6 +18,10 @@ var staff = module.exports = { fields: { user: "_id username displayName photo created_at updated_at last_seen created_ip last_ip", project: "_id name slug user_id privacy created_at updated_at", + plans: "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " + + "pro_layout_monthly_price pro_layout_yearly_price " + + "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit", + plans_permissions: "basic_editor pro_editor solids collaborators no_logo", }, defaults: { @@ -122,8 +126,8 @@ var staff = module.exports = { }, ensurePlans: function(req, res, next){ - Plan.exec(function (err, plans) { - res.locals.plans = plans.map(staff.helpers.plan) + Plan.find(function (err, plans) { + res.locals.plans = (plans || []).map(staff.helpers.plan) next() }) }, @@ -132,17 +136,16 @@ var staff = module.exports = { Plan.findOne({ slug: req.params.slug }, function(err, plan){ if (err || ! plan) { console.error(err) - req.plan = null + res.redirect("/staff/plans/") } else { req.plan = plan + next() } - next() }) } else { - req.plan = null - next() + res.redirect("/staff/plans/") } }, @@ -326,7 +329,14 @@ var staff = module.exports = { media.user = {} media.shortUrl = media.url.replace(/^http.:\/\//,"") return media - } + }, + + plan: function(plan){ + plan = plan.toObject() + plan.date = moment( plan.updated_at || plan.created_at ).format("M/DD/YYYY hh:mm a") + plan.user = {} + return plan + }, }, route: function(app){ @@ -452,7 +462,8 @@ var staff = module.exports = { // // plans - app.get('/staff/plans/', + + app.get('/staff/plans', middleware.ensureAuthenticated, middleware.ensureIsStaff, @@ -484,6 +495,8 @@ var staff = module.exports = { middleware.ensureAuthenticated, middleware.ensureIsStaff, + staff.middleware.ensurePlan, + staff.plans.update ); }, @@ -607,14 +620,8 @@ var staff = module.exports = { plans: { index: function(req, res){ - res.locals.fields = ( - "monthly_price yearly_price basic_layout_monthly_price basic_layout_yearly_price " + - "pro_layout_monthly_price pro_layout_yearly_price " + - "basic_layout_limit pro_layout_limit stock_project_limit basic_project_limit pro_project_limit" - ).split(" ") - - res.locals.permissions = "basic_editor pro_editor solids collaborators no_logo".split(" ") - + res.locals.fields = staff.fields.plans.split(" ") + res.locals.permissions = staff.fields.plans_permissions.split(" ") res.render('staff/plans/index') }, new: function(req, res){ @@ -625,10 +632,37 @@ var staff = module.exports = { res.render('staff/plans/edit') }, create: function(req, res){ - res.redirect("/staff/plans/") + var plan = new Plan () + var fields = staff.fields.plans.split(" ") + var permissions = staff.fields.plans_permissions.split(" ") + + var data = util.cleanQuery(req.body) + data.name = util.sanitize(data.name) + data.slug = util.sanitize(data.slug.toLowerCase()) + + permissions.forEach(function(field){ + data[field] = data["permissions_" + field] + }) + + new Plan (data).save(function(err, doc){ + if (err || ! doc) { return res.json({ error: err }) } + res.redirect("/staff/plans/") + }) }, update: function(req, res){ - res.redirect("/staff/plans/") + var data = util.cleanQuery(req.body) + data.name = util.sanitize(data.name) + data.slug = util.sanitize(data.slug.toLowerCase()) + + _.extend(req.plan, data) + permissions.forEach(function(field){ + req.plan[field] = data["permissions_" + field] + }) + + req.plan.save(function(err, doc){ + if (err || ! doc) { return res.json({ error: err }) } + res.redirect("/staff/plans/") + }) }, } diff --git a/server/repl.js b/server/repl.js index ba94d45..353d8c5 100644 --- a/server/repl.js +++ b/server/repl.js @@ -9,6 +9,8 @@ mongoose.connect('mongodb://' + DB_HOST + '/vvalls', {}, function(){ "./lib/schemas/Layout", "./lib/schemas/Media", "./lib/schemas/Project", + "./lib/schemas/Plan", + "./lib/schemas/Subscription", ].forEach(function(modName){ // console.log(name, modName) var namez = modName.split("/"), name = namez[namez.length-1]; diff --git a/views/staff/_nav.ejs b/views/staff/_nav.ejs index 2115e9f..db7bedb 100644 --- a/views/staff/_nav.ejs +++ b/views/staff/_nav.ejs @@ -3,4 +3,5 @@ <a href="/staff/users">users</a> <a href="/staff/projects">projects</a> <a href="/staff/media">media</a> + <a href="/staff/plans">plans</a> </nav>
\ No newline at end of file diff --git a/views/staff/index.ejs b/views/staff/index.ejs index 5ca7269..1b73641 100644 --- a/views/staff/index.ejs +++ b/views/staff/index.ejs @@ -2,11 +2,7 @@ <h1>Staff Area</h1> - <nav> - <a href="/staff/users">users</a> - <a href="/staff/projects">projects</a> - <a href="/staff/media">media</a> - </nav> + [[ include _nav ]] <hr> diff --git a/views/staff/plans/_form.ejs b/views/staff/plans/_form.ejs index b97716f..fc86516 100644 --- a/views/staff/plans/_form.ejs +++ b/views/staff/plans/_form.ejs @@ -1,109 +1,149 @@ +<input type="hidden" id="_csrf" name="_csrf" value="[[- token ]]"> -<div> +<ul> + +<li class="section_break"> + <h3>New Plan</h3> +</li> + +<li> <label for="plan_name">Name</label> - <input id="plan_name" name="name" type="text" value="[[- plan.name ]]"> -</div> + <div><input id="plan_name" name="name" type="text" value="[[- plan.name ]]"></div> +</li> -<div> +<li> <label for="plan_slug">Slug</label> - <input id="plan_slug" name="slug" type="text" value="[[- plan.slug ]]"> -</div> + <div><input id="plan_slug" name="slug" type="text" value="[[- plan.slug ]]"></div> +</li> <!-- - - - - --> -<div> +<li class="section_break"> + <h3>Plan Pricing</h3> +</li> + +<li> <label for="plan_monthly_price">Monthly Price</label> - <input id="plan_monthly_price" name="monthly_price" type="number" value="[[- plan.monthly_price ]]"> -</div> + <div><input id="plan_monthly_price" name="monthly_price" type="number" value="[[- plan.monthly_price ]]"></div> +</li> -<div> +<li> <label for="plan_yearly_price">Yearly Price</label> - <input id="plan_yearly_price" name="yearly_price" type="number" value="[[- plan.yearly_price ]]"> -</div> + <div><input id="plan_yearly_price" name="yearly_price" type="number" value="[[- plan.yearly_price ]]"></div> +</li> + +<p> + <i>Note:</i> Pricing should be in cents, i.e. a price of $10.00 should be entered as 1000. +</p> <!-- - - - - --> -<div> - <label for="plan_basic_layout_monthly_price">Basic Layout Price (Monthly)</label> - <input id="plan_basic_layout_monthly_price" name="basic_layout_monthly_price" type="number" value="[[- plan.basic_layout_monthly_price ]]"> -</div> +<li class="section_break"> + <h3>Additional Template Pricing</h3> +</li> -<div> - <label for="plan_basic_layout_yearly_price">Basic Layout Price (Yearly)</label> - <input id="plan_basic_layout_yearly_price" name="basic_layout_yearly_price" type="number" value="[[- plan.basic_layout_yearly_price ]]"> -</div> +<li> + <label for="plan_basic_layout_monthly_price">Basic Template Price (Monthly)</label> + <div><input id="plan_basic_layout_monthly_price" name="basic_layout_monthly_price" type="number" value="[[- plan.basic_layout_monthly_price ]]"></div> +</li> -<div> - <label for="plan_pro_layout_monthly_price">Pro Layout Price (Monthly)</label> - <input id="plan_pro_layout_monthly_price" name="pro_layout_monthly_price" type="number" value="[[- plan.pro_layout_monthly_price ]]"> -</div> +<li> + <label for="plan_basic_layout_yearly_price">Basic Template Price (Yearly)</label> + <div><input id="plan_basic_layout_yearly_price" name="basic_layout_yearly_price" type="number" value="[[- plan.basic_layout_yearly_price ]]"></div> +</li> -<div> - <label for="plan_pro_layout_yearly_price">Pro Layout Price (Yearly)</label> - <input id="plan_pro_layout_yearly_price" name="pro_layout_yearly_price" type="number" value="[[- plan.pro_layout_yearly_price ]]"> -</div> +<li> + <label for="plan_pro_layout_monthly_price">Pro Template Price (Monthly)</label> + <div><input id="plan_pro_layout_monthly_price" name="pro_layout_monthly_price" type="number" value="[[- plan.pro_layout_monthly_price ]]"></div> +</li> + +<li> + <label for="plan_pro_layout_yearly_price">Pro Template Price (Yearly)</label> + <div><input id="plan_pro_layout_yearly_price" name="pro_layout_yearly_price" type="number" value="[[- plan.pro_layout_yearly_price ]]"></div> +</li> <!-- - - - - --> -<div> - <label for="plan_basic_layout_limit">Basic Layout Limit</label> - <input id="plan_basic_layout_limit" name="basic_layout_limit" type="number" value="[[- plan.basic_layout_limit ]]"> -</div> +<li class="section_break"> + <h3>Per-Plan Template Limits</h3> +</li> -<div> - <label for="plan_pro_layout_limit">Pro Layout Limit</label> - <input id="plan_pro_layout_limit" name="pro_layout_limit" type="number" value="[[- plan.pro_layout_limit ]]"> -</div> +<li> + <label for="plan_basic_layout_limit">Basic Template Limit</label> + <div><input id="plan_basic_layout_limit" name="basic_layout_limit" type="number" value="[[- plan.basic_layout_limit ]]"></div> +</li> + +<li> + <label for="plan_pro_layout_limit">Pro Template Limit</label> + <div><input id="plan_pro_layout_limit" name="pro_layout_limit" type="number" value="[[- plan.pro_layout_limit ]]"></div> +</li> <!-- - - - - --> -<div> +<li class="section_break"> + <h3>Per-Plan Project Limits</h3> +</li> + +<li> <label for="plan_stock_project_limit">Stock Project Limit</label> - <input id="plan_stock_project_limit" name="stock_project_limit" type="number" value="[[- plan.stock_project_limit ]]"> -</div> + <div><input id="plan_stock_project_limit" name="stock_project_limit" type="number" value="[[- plan.stock_project_limit ]]"></div> +</li> -<div> +<li> <label for="plan_basic_project_limit">Basic Project Limit</label> - <input id="plan_basic_project_limit" name="basic_project_limit" type="number" value="[[- plan.basic_project_limit ]]"> -</div> + <div><input id="plan_basic_project_limit" name="basic_project_limit" type="number" value="[[- plan.basic_project_limit ]]"></div> +</li> -<div> +<li> <label for="plan_pro_project_limit">Pro Layout Limit</label> - <input id="plan_pro_project_limit" name="pro_project_limit" type="number" value="[[- plan.pro_project_limit ]]"> -</div> + <div><input id="plan_pro_project_limit" name="pro_project_limit" type="number" value="[[- plan.pro_project_limit ]]"></div> +</li> <!-- - - - - --> +<li class="section_break"> + <h3>Permissions</h3> +</li> + <div> - <label for="plan_permissions_basic_editor">Basic Editor</label> +<li> <input id="plan_permissions_basic_editor" name="permissions_basic_editor" type="hidden" value="0"> <input id="plan_permissions_basic_editor" name="permissions_basic_editor" type="checkbox" value="1" [[ if (plan.permissions.basic_editor) { ]]checked[[ } ]]> -</div> + <label for="plan_permissions_basic_editor">Basic Editor</label> +</li> -<div> - <label for="plan_permissions_pro_editor">Pro Editor</label> +<li> <input id="plan_permissions_pro_editor" name="permissions_pro_editor" type="hidden" value="0"> <input id="plan_permissions_pro_editor" name="permissions_pro_editor" type="checkbox" value="1" [[ if (plan.permissions.pro_editor) { ]]checked[[ } ]]> -</div> + <label for="plan_permissions_pro_editor">Pro Editor</label> +</li> -<div> - <label for="plan_permissions_solids">3D Objects</label> +<li> <input id="plan_permissions_solids" name="permissions_solids" type="hidden" value="0"> <input id="plan_permissions_solids" name="permissions_solids" type="checkbox" value="1" [[ if (plan.permissions.solids) { ]]checked[[ } ]]> -</div> + <label for="plan_permissions_solids">3D Objects</label> +</li> -<div> - <label for="plan_permissions_collaborators">Collaborators</label> +<li> <input id="plan_permissions_collaborators" name="permissions_collaborators" type="hidden" value="0"> <input id="plan_permissions_collaborators" name="permissions_collaborators" type="checkbox" value="1" [[ if (plan.permissions.collaborators) { ]]checked[[ } ]]> -</div> + <label for="plan_permissions_collaborators">Collaborators</label> +</li> -<div> - <label for="plan_permissions_no_logo">No Logo</label> +<li> <input id="plan_permissions_no_logo" name="permissions_no_logo" type="hidden" value="0"> <input id="plan_permissions_no_logo" name="permissions_no_logo" type="checkbox" value="1" [[ if (plan.permissions.no_logo) { ]]checked[[ } ]]> -</div> + <label for="plan_permissions_no_logo">No Logo</label> +</li> + +<p> + These permissions should harmonize with the restrictions on layouts set above. +</p> +</div> -<input type="submit" value="Save Changes"> +<li> + <input type="submit" value="Save Changes"> +</li> +</ul> diff --git a/views/staff/plans/edit.ejs b/views/staff/plans/edit.ejs index 503c97d..9848873 100644 --- a/views/staff/plans/edit.ejs +++ b/views/staff/plans/edit.ejs @@ -7,7 +7,7 @@ <hr> <form action="" method="post"> -[[- include form ]] +[[- include _form ]] </form> [[ include ../_footer ]] diff --git a/views/staff/plans/index.ejs b/views/staff/plans/index.ejs index aa6c35a..121a2fc 100644 --- a/views/staff/plans/index.ejs +++ b/views/staff/plans/index.ejs @@ -6,6 +6,7 @@ <hr> +[[ if (plans.length) { ]] <table> <tr> <td></td> @@ -30,7 +31,11 @@ <td>[[- field.replace(/_/," ") ]]</td> [[ plans.forEach(function(plan){ ]] <td> - [[- plan[field] ]] + [[ if (field.indexOf("_price") != -1) { ]] + [[- plan[field] == 0 ? "" : "$" + (plan[field]/100).toFixed(2) ]] + [[ } else { ]] + [[- plan[field] ]] + [[ } ]] </td> [[ }) ]] </tr> @@ -46,8 +51,10 @@ [[ }) ]] </tr> [[ }) ]] - </table> +<br clear="all"> +[[ } ]] + <a href="/staff/plans/new">New Plan</a> <hr> diff --git a/views/staff/plans/new.ejs b/views/staff/plans/new.ejs index d56a1c3..297d3d6 100644 --- a/views/staff/plans/new.ejs +++ b/views/staff/plans/new.ejs @@ -7,9 +7,7 @@ <hr> <form action="" method="post"> -[[- include form ]] +[[- include _form ]] </form> [[ include ../_footer ]] - - |
