diff --git a/common/models/pledge.json b/common/models/pledge.json index b563d4629e..08e46df414 100644 --- a/common/models/pledge.json +++ b/common/models/pledge.json @@ -5,7 +5,8 @@ "trackChanges": false, "properties": { "nonprofit": { - "type": "string" + "type": "string", + "index": true }, "amount": { "type": "number" @@ -16,13 +17,24 @@ }, "dateEnded": { "type": "date" + }, + "formerUserId": { + "type": "string" + }, + "isOrphaned": { + "type": "boolean" + }, + "isCompleted": { + "type": "boolean", + "default": "false" } }, "validations": [], "relations": { - "camper": { + "user": { "type": "hasMany", - "model": "user" + "model": "user", + "foreignKey": "userId" } }, "acls": [ @@ -39,16 +51,5 @@ "permission": "ALLOW" } ], - "methods": [], - "indexes": { - "nonprofit_amount":{ - "keys": { - "nonprofit": 1, - "amount": 1 - }, - "options": { - "unique": true - } - } - } + "methods": [] } diff --git a/common/models/user.json b/common/models/user.json index 776c2c500e..f85cc1023c 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -166,6 +166,11 @@ "type": "hasMany", "model": "userIdentity", "foreignKey": "" + }, + "pledge": { + "type": "hasOne", + "model": "pledge", + "foreignKey": "" } }, "acls": [ diff --git a/server/boot/commit.js b/server/boot/commit.js index 40203fca32..be08d85348 100644 --- a/server/boot/commit.js +++ b/server/boot/commit.js @@ -1,16 +1,33 @@ +import _ from 'lodash'; +import debugFactory from 'debug'; import dedent from 'dedent'; +import nonprofits from '../utils/commit.json'; + +import { + unDasherize +} from '../utils'; + +import { + observeQuery, + saveInstance +} from '../utils/rx'; + import { ifNoUserRedirectTo } from '../utils/middleware'; const sendNonUserToFront = ifNoUserRedirectTo('/'); +const debug = debugFactory('freecc:commit'); export default function commit(app) { const router = app.loopback.Router(); + const { Pledge } = app.models; + router.get( '/commit', commitToNonprofit ); + router.get( '/commit/pledge', sendNonUserToFront, @@ -20,27 +37,72 @@ export default function commit(app) { app.use(router); function commitToNonprofit(req, res) { - res.render('commit/', { - title: 'Commit to a nonprofit. Commit to your goal.' - }); + let nonprofitName = unDasherize(req.query.nonprofit); + let nonprofit; + + debug('looking for nonprofit', nonprofitName); + if (nonprofitName) { + nonprofit = _.find(nonprofits, (nonprofit) => { + return nonprofitName === nonprofit.name; + }); + } + + nonprofit = nonprofit || nonprofits[0]; + + res.render( + 'commit/', + Object.assign( + { title: 'Commit to a nonprofit. Commit to your goal.' }, + nonprofit + ) + ); } - function pledge(req, res) { + function pledge(req, res, next) { const { user } = req; const { nonprofit = 'girl develop it', amount = '5', - goal = 'front end certification' + goal = 'Front End Development Certification' } = req.query; - req.flash('success', { - msg: dedent` - Congratulations, you have commit to giving ${nonprofit} ${amount} - dollars a month until you have reached your goal - of completing your ${goal} - ` - }); + observeQuery(user, 'pledge') + .flatMap(oldPledge => { + // create new pledge for user + const pledge = Pledge({ + nonprofit, + amount, + goal, + userId: user.id + }); + + if (oldPledge) { + debug('user already has pledge, creating a new one'); + // we orphan last pledge since a user only has one pledge at a time + oldPledge.userId = ''; + oldPledge.formerUser = user.id; + oldPledge.endDate = new Date(); + oldPledge.isOrphaned = true; + return saveInstance(oldPledge) + .flatMap(() => { + return saveInstance(pledge); + }); + } + return saveInstance(pledge); + }) + .subscribe( + ({ nonprofit, goal, amount }) => { + req.flash('success', { + msg: dedent` + Congratulations, you have committed to giving + ${nonprofit} $${amount} each month until you have completed + your ${goal}. + ` + }); + res.redirect('/' + user.username); + }, + next + ); - res.redirect('/' + user.username); } } diff --git a/server/utils/commit.json b/server/utils/commit.json new file mode 100644 index 0000000000..41d16d36c8 --- /dev/null +++ b/server/utils/commit.json @@ -0,0 +1,10 @@ +[ + { + "name": "girl develop it", + "displayName": "Girl Develop It", + "donateUrl": "https://www.girldevelopit.com/donate", + "description": "Girl Develop It provides in-person classes for women to learn to code.", + "imgAlt": "Girl Develop It participants coding at tables.", + "imgUrl": "http://i.imgur.com/U1CyEuA.jpg" + } +] diff --git a/server/views/commit/index.jade b/server/views/commit/index.jade index 7fd469ca1a..1402545af7 100644 --- a/server/views/commit/index.jade +++ b/server/views/commit/index.jade @@ -5,48 +5,49 @@ block content h3.text-center Commit to yourself. Commit to a nonprofit. .row .col-xs-12.col-sm-6.col-sm-offset-3 - p Are you looking for a burst of motivation? Do you want to help nonprofits before you’re ready to code for them? You can do both by pledging a monthly donation to a nonprofit until you've earned either your Front End or Full Stack Development certificate. Join Commit below or click "maybe later". + p Give yourself ongoing motivation and help nonprofits right away. Pledge a monthly donation to a nonprofit until you’ve earned either your Front End or Full Stack Development Certification. .row .col-xs-12.col-sm-6.col-sm-offset-3.text-center - h4 Our Featured Nonprofit - a(href="http://i.imgur.com/U1CyEuA.jpg" data-lightbox="img-enlarge") - img.img-responsive(src='http://i.imgur.com/U1CyEuA.jpg' alt="Girl Develop It participants coding at tables.") - p Girl Develop It is a nonprofit that provides in-person classes for women to learn to code. - .spacer + h4 Pledge to #{displayName} + .spacer + a(href='#{imgUrl}' data-lightbox='img-enlarge' alt='#{imgAlt}') + img.img-responsive(src='#{imgUrl}' alt='#{imgAlt}') + p= description + a or browse our directory + .spacer form.form(name='commit') .hidden - input(type='text' value='girl develop it' name='nonprofit') + input(type='text' value='#{name}' name='nonprofit') .row .col-xs-12.col-sm-6.col-sm-offset-3 - h4 Step 1: Choose your goal + h4 Choose your goal: .btn-group.btn-group-justified(data-toggle='buttons' role='group') - label.btn.btn-info.active - input(type='radio' id='front-end-development-certificate' value='front end certification' name='goal' checked="checked") + label.btn.btn-primary.btn-lg.active + input(type='radio' id='front-end-development-certificate' value='Front End Development Certification' name='goal' checked="checked") | Front End Development Certificate (takes about 400 hours) - label.btn.btn-info - input(type='radio' id='full-stack-development-certificate' value='full stack certification' name='goal') + label.btn.btn-primary.btn-lg + input(type='radio' id='full-stack-development-certificate' value='Full Stack Development Certification' name='goal') | Full Stack Development Certificate (takes about 800 hours) - .spacer + .spacer .row .col-xs-12.col-sm-6.col-sm-offset-3 - h4 Step 2: Choose how much you want to donate each month + h4 Choose how much you want to pledge each month: .btn-group.btn-group-justified(data-toggle='buttons' role='group') - label.btn.btn-primary + label.btn.btn-success input(type='radio' id='5-dollar-pledge' value='5' name='amount') | $5 per month - label.btn.btn-primary.active + label.btn.btn-success.active input(type='radio' id='10-dollar-pledge' value='10' name='amount' checked="checked") | $10 per month - label.btn.btn-primary + label.btn.btn-success input(type='radio' id='50-dollar-pledge' value='50' name='amount') | $50 per month - .spacer + .spacer .row - .col-xs-12.col-sm-6.col-sm-offset-3 - h4 Step 3: Commit - a#commit-btn-submit.btn.btn-block.btn-primary(href='https://www.girldevelopit.com/donate' target='_blank') Commit + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + a#commit-btn-submit.btn.btn-block.btn-lg.signup-btn(href='https://www.girldevelopit.com/donate' target='_blank') Commit (and open donate page) .button-spacer - a.btn.btn-block.btn-warning(href='/') Maybe later + a(href='/') Maybe later .spacer script. $(function() {