Skip to content

Instantly share code, notes, and snippets.

@dvdsgl
Last active December 17, 2015 22:29
Show Gist options
  • Save dvdsgl/5682200 to your computer and use it in GitHub Desktop.
Save dvdsgl/5682200 to your computer and use it in GitHub Desktop.
class Enum
constructor: (@names...) ->
@values = [0 .. @names.length - 1]
@[name] = i for name, i in @names
getName: (i) => @names[i]
getTitle: (i) => _.str.titleize @getName i
# The next few definitions (e.g. Trial, Tiles) are for the interpretation of valid tile state
Trial = new Enum "available", "active", "expired"
Subscription = new Enum "inactive", "active", "renew", "expired"
Tier = new Enum "starter", "indie", "business", "enterprise"
class ActivationRules
# Tile predicate authentication decorator
authenticate = (predicate) ->
(state) -> state.authenticated and predicate state
rules = [
{
name: "signed-out"
predicate: ({authenticated}) -> !authenticated
}, {
name: "trial-available"
priority: 7
predicate: authenticate ({tier, trial}) ->
trial is Trial.available and tier < Tier.business
}, {
name: "trial-started"
priority: 7
predicate: authenticate ({tier, trial}) ->
trial is Trial.active and tier < Tier.business
}, {
name: "trial-expired"
priority: 7
predicate: authenticate ({tier, trial}) ->
trial is Trial.expired and tier < Tier.business
}, {
name: "inactive"
predicate: authenticate ({subscription, tier}) ->
Tier.starter < tier and subscription is Subscription.inactive
}, {
name: "activated"
predicate: authenticate ({subscription, tier}) ->
Tier.starter < tier and subscription is Subscription.active
}, {
name: "renew-soon"
priority: 8
predicate: authenticate ({subscription, tier}) ->
Tier.starter < tier and subscription is Subscription.renew
}, {
name: "subscription-expired"
priority: 10
predicate: authenticate ({subscription, tier}) ->
Tier.starter < tier and subscription is Subscription.expired
}, {
name: "invitation-received"
priority: 9
predicate: authenticate ({tier, invited}) ->
invited and tier is Tier.starter
}, {
name: "starter-upgrade"
predicate: authenticate ({trial, tier}) ->
tier is Tier.starter and trial isnt Trial.active
},
]
# Gets prioritized rules for a given activation state
# { invited: bool, authenticated: bool, trial: Trial, tier: Tier, subscription: Subscription }
@getRules: (state) ->
_.chain(rules)
.filter(({predicate}) -> predicate state)
.sortBy((rule) -> rule.priority or 0)
.map(({name}) -> name)
.reverse()
.value()
# Builds controls for manipulating activation state
# handle receives activation state, rules
@getControls: (handle) ->
state =
invited: false
authenticated: false
trial: Trial.available
tier: Tier.starter
subscription: Subscription.inactive
set = (s) ->
state = _.extend state, s
handle state, ActivationRules.getRules state
e = $ "<div>"
e.append $ "<h6>User is signed in</h6>"
e.append Quick.makeSwitch (auth) =>
set authenticated: auth
e.append $ "<h6>Trial</h6>"
e.append Quick.makeButtonBar Trial.values, state.trial, Trial.getTitle, (trial) =>
set trial: trial
e.append $ "<h6>Tier</h6>"
e.append Quick.makeButtonBar Tier.values, state.tier, Tier.getTitle, (tier) =>
set tier: tier
e.append $ "<h6>Subscription</h6>"
e.append Quick.makeButtonBar Subscription.values, state.subscription, Subscription.getTitle, (sub) =>
set subscription: sub
e.append $ "<h6>Pending Invitation</h6>"
e.append Quick.makeSwitch (invited) =>
set invited: invited
# Send initial state
set {}
e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment