ducky/web

Paddy 2015-07-07 Parent:13d27b50d79e Child:21f80f56cda9

21:bc1478742a50 Browse Files

Implement subscriptions. Create a Subscription model and a Subscriptions collection, and attach them to the app context. Add a helper to our Profile model to retrieve the Subscription of that model. Still not sure this should be on the Profile--wouldn't it be better on the Me model? Isn't that generally where we would need it?

src/main.js src/models/profile.js src/models/subscription.js src/models/subscriptions.js

     1.1 --- a/src/main.js	Tue Jul 07 21:25:49 2015 -0400
     1.2 +++ b/src/main.js	Tue Jul 07 21:29:19 2015 -0400
     1.3 @@ -1,6 +1,7 @@
     1.4  import app from 'ampersand-app'
     1.5  import Router from './router'
     1.6  import Profiles from './models/profiles'
     1.7 +import Subscriptions from './models/subscriptions'
     1.8  import Me from './models/me'
     1.9  import normalize from 'normalize.css/normalize.css'
    1.10  import styles from './styles/main.scss'
    1.11 @@ -8,10 +9,11 @@
    1.12  window.app = app.extend({
    1.13    init () {
    1.14      this.profiles = new Profiles()
    1.15 +    this.subscriptions = new Subscriptions()
    1.16      this.me = new Me().load()
    1.17      this.me.on('change', this.me.debouncedWriteToCache)
    1.18      this.router = new Router()
    1.19 -    this.router.history.start({ pushState: true })
    1.20 +    this.router.history.start()
    1.21    }
    1.22  })
    1.23  
     2.1 --- a/src/models/profile.js	Tue Jul 07 21:25:49 2015 -0400
     2.2 +++ b/src/models/profile.js	Tue Jul 07 21:29:19 2015 -0400
     2.3 @@ -23,4 +23,16 @@
     2.4        }
     2.5      }
     2.6    },
     2.7 +
     2.8 +  subscription() {
     2.9 +    return new Promise((resolve, reject) => {
    2.10 +      app.subscriptions.getOrFetch(this.id, (err, model) => {
    2.11 +        if (err) {
    2.12 +          reject(err)
    2.13 +        } else {
    2.14 +          resolve(model)
    2.15 +        }
    2.16 +      })
    2.17 +    })
    2.18 +  },
    2.19  })
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/models/subscription.js	Tue Jul 07 21:29:19 2015 -0400
     3.3 @@ -0,0 +1,47 @@
     3.4 +import Model from 'ampersand-model'
     3.5 +import refresh from '../helpers/oauth-refresh'
     3.6 +
     3.7 +export default Model.extend({
     3.8 +  props: {
     3.9 +    'userID': 'string',
    3.10 +    'stripe_subscription': 'string',
    3.11 +    'plan': 'string',
    3.12 +    'status': 'string',
    3.13 +    'canceling': 'boolean',
    3.14 +    'created': 'date',
    3.15 +    'trialStart': 'date',
    3.16 +    'trialEnd': 'date',
    3.17 +    'periodStart': 'date',
    3.18 +    'periodEnd': 'date',
    3.19 +    'canceledAt': 'date',
    3.20 +    'failedChargeAttempts': 'integer',
    3.21 +    'lastFailedCharge': 'date',
    3.22 +    'lastNotified': 'date',
    3.23 +  },
    3.24 +  idAttribute: 'userID',
    3.25 +  sync: refresh.Sync,
    3.26 +  parse (attrs) {
    3.27 +    if (attrs.subscriptions && attrs.subscriptions.length == 1) {
    3.28 +      attrs = attrs.subscriptions[0]
    3.29 +    }
    3.30 +    attrs.userID = attrs.user_id
    3.31 +    attrs.stripeSubscription = attrs.stripeSubscription
    3.32 +    attrs.trialStart = attrs.trial_start
    3.33 +    attrs.trialEnd = attrs.trial_end
    3.34 +    attrs.periodStart = attrs.period_start
    3.35 +    attrs.periodEnd = attrs.period_end
    3.36 +    attrs.canceledAt = attrs.canceled_at
    3.37 +    attrs.failedChargeAttempts = attrs.failed_charge_attempts
    3.38 +    attrs.lastFailedCharge = attrs.last_failed_charge
    3.39 +    attrs.lastNotified = attrs.last_notified
    3.40 +    return attrs
    3.41 +  },
    3.42 +  ajaxConfig () {
    3.43 +    return {
    3.44 +      headers: {
    3.45 +        'Authorization': 'Bearer '+app.me.access_token,
    3.46 +        'Accept': 'application/json',
    3.47 +      }
    3.48 +    }
    3.49 +  },
    3.50 +})
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/models/subscriptions.js	Tue Jul 07 21:29:19 2015 -0400
     4.3 @@ -0,0 +1,46 @@
     4.4 +import Collection from 'ampersand-rest-collection'
     4.5 +import Subscription from './subscription'
     4.6 +import config from '../config'
     4.7 +import refresh from '../helpers/oauth-refresh'
     4.8 +import app from 'ampersand-app'
     4.9 +import isObject from 'lodash.isobject'
    4.10 +
    4.11 +export default Collection.extend({
    4.12 +  model: Subscription,
    4.13 +  url: config.urlBase + '/subscriptions/subscriptions',
    4.14 +  ajaxConfig () {
    4.15 +    return {
    4.16 +      headers: {
    4.17 +        'Authorization': 'Bearer '+app.me.access_token,
    4.18 +        'Accept': 'application/json',
    4.19 +      }
    4.20 +    }
    4.21 +  },
    4.22 +
    4.23 +  sync: refresh.Sync,
    4.24 +
    4.25 +  create (params) {
    4.26 +    let options = {
    4.27 +      data: JSON.stringify({
    4.28 +        'user_id': params.user_id,
    4.29 +        'email': params.email,
    4.30 +        'stripe_token': params.stripe_token,
    4.31 +        'plan': params.plan,
    4.32 +      }),
    4.33 +    }
    4.34 +    let moc = this
    4.35 +    options.success = function(resp) {
    4.36 +      let serverAttrs = moc.parse(resp, options)
    4.37 +      if (options.wait) serverAttrs = assign({}, serverAttrs)
    4.38 +      if (isObject(serverAttrs) && !moc.set(serverAttrs, options)) {
    4.39 +        // TODO: throw error?
    4.40 +        return
    4.41 +      }
    4.42 +      moc.trigger('sync', moc, resp, options)
    4.43 +    }
    4.44 +    options.error = function(resp) {
    4.45 +      moc.trigger('error', moc, resp, options)
    4.46 +    }
    4.47 +    refresh.Sync('create', moc, options)
    4.48 +  }
    4.49 +})