Have the private option in the new repo form alert the user about needing to purchase a plan and let them do so

This commit is contained in:
Joseph Schorr 2013-10-28 17:08:26 -04:00
parent bb2446c45c
commit 1ee21318d4
4 changed files with 133 additions and 36 deletions

View file

@ -130,6 +130,16 @@
text-decoration: none !important;
}
.new-repo .required-plan {
margin: 10px;
margin-top: 20px;
margin-left: 50px;
}
.new-repo .required-plan .alert {
color: #444 !important;
}
.new-repo .new-header {
font-size: 22px;
}

View file

@ -54,7 +54,7 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics',
return keyService;
}]);
$provide.factory('PlanService', [function() {
$provide.factory('PlanService', ['Restangular', 'KeyService', function(Restangular, KeyService) {
var plans = [
{
title: 'Open Source',
@ -96,11 +96,54 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics',
planService.planList = function() {
return plans;
}
};
planService.getPlan = function(planId) {
return planDict[planId];
}
};
planService.getMinimumPlan = function(privateCount) {
for (var i = 0; i < plans.length; i++) {
var plan = plans[i];
if (plan.privateRepos >= privateCount) {
return plan;
}
}
return null;
};
planService.showSubscribeDialog = function($scope, planId, started, success, failed) {
var submitToken = function(token) {
$scope.$apply(function() {
started();
});
mixpanel.track('plan_subscribe');
var subscriptionDetails = {
token: token.id,
plan: planId,
};
var createSubscriptionRequest = Restangular.one('user/plan');
$scope.$apply(function() {
createSubscriptionRequest.customPUT(subscriptionDetails).then(success, failed);
});
};
var planDetails = planService.getPlan(planId)
StripeCheckout.open({
key: KeyService.stripePublishableKey,
address: false, // TODO change to true
amount: planDetails.price,
currency: 'usd',
name: 'Quay ' + planDetails.title + ' Subscription',
description: 'Up to ' + planDetails.privateRepos + ' private repositories',
panelLabel: 'Subscribe',
token: submitToken
});
};
return planService;
}]);

View file

@ -701,6 +701,8 @@ function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService,
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
$scope.errorMessage = 'You are using more private repositories than your plan allows, please upgrate your subscription to avoid disruptions in your service.';
} else {
$scope.errorMessage = null;
}
$scope.planLoading = false;
@ -709,7 +711,7 @@ function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService,
mixpanel.people.set({
'plan': sub.plan
});
}
};
$scope.planLoading = true;
var getSubscription = Restangular.one('user/plan');
@ -720,36 +722,16 @@ function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService,
$scope.planChanging = false;
$scope.subscribe = function(planId) {
var submitToken = function(token) {
$scope.$apply(function() {
mixpanel.track('plan_subscribe');
$scope.planChanging = true;
$scope.errorMessage = undefined;
var subscriptionDetails = {
token: token.id,
plan: planId,
};
var createSubscriptionRequest = Restangular.one('user/plan');
createSubscriptionRequest.customPUT(subscriptionDetails).then(subscribedToPlan, function() {
// Failure
$scope.errorMessage = 'Unable to subscribe.';
});
});
};
var planDetails = PlanService.getPlan(planId)
StripeCheckout.open({
key: KeyService.stripePublishableKey,
address: false, // TODO change to true
amount: planDetails.price,
currency: 'usd',
name: 'Quay ' + planDetails.title + ' Subscription',
description: 'Up to ' + planDetails.privateRepos + ' private repositories',
panelLabel: 'Subscribe',
token: submitToken
PlanService.showSubscribeDialog($scope, planId, function() {
// Subscribing.
$scope.planChanging = true;
}, function(plan) {
// Subscribed.
subscribedToPlan(plan);
}, function() {
// Failure.
$scope.errorMessage = 'Unable to subscribe.';
$scope.planChanging = false;
});
};
@ -920,7 +902,7 @@ function V1Ctrl($scope, $location, UserService) {
};
}
function NewRepoCtrl($scope, $location, $http, UserService, Restangular) {
function NewRepoCtrl($scope, $location, $http, UserService, Restangular, PlanService) {
$scope.repo = {
'is_public': 1,
'description': '',
@ -999,6 +981,16 @@ function NewRepoCtrl($scope, $location, $http, UserService, Restangular) {
});
};
var subscribedToPlan = function(sub) {
$scope.planChanging = false;
$scope.subscription = sub;
$scope.subscribedPlan = PlanService.getPlan(sub.plan);
$scope.planRequired = null;
if ($scope.subscription.usedPrivateRepos >= $scope.subscribedPlan.privateRepos) {
$scope.planRequired = PlanService.getMinimumPlan($scope.subscription.usedPrivateRepos);
}
};
$scope.$watch( function () { return UserService.currentUser(); }, function (currentUser) {
$scope.user = currentUser;
@ -1061,4 +1053,28 @@ function NewRepoCtrl($scope, $location, $http, UserService, Restangular) {
$scope.creating = false;
});
};
$scope.upgradePlan = function() {
PlanService.showSubscribeDialog($scope, $scope.planRequired.stripeId, function() {
// Subscribing.
$scope.planChanging = true;
}, function(plan) {
// Subscribed.
subscribedToPlan(plan);
}, function() {
// Failure.
$('#couldnotsubscribeModal').modal();
$scope.planChanging = false;
});
};
$scope.plans = PlanService.planList();
// Load the user's subscription information in case they want to create a private
// repository.
var getSubscription = Restangular.one('user/plan');
getSubscription.get().then(subscribedToPlan, function() {
// User has no subscription
$scope.planRequired = PlanService.getMinimumPlan(1);
});
}

View file

@ -62,6 +62,15 @@
<span class="description-text">You choose who can see, pull and push from/to this repository.</span>
</div>
</div>
<!-- Payment -->
<div class="required-plan" ng-show="repo.is_public == '0' && planRequired">
<div class="alert alert-warning">
In order to make this repository private, youll need to upgrade your plan from <b>{{ subscribedPlan.title }}</b> to <b>{{ planRequired.title }}</b>. This will cost $<span>{{ planRequired.price / 100 }}</span>/month.
</div>
<a class="btn btn-primary" ng-click="upgradePlan()" ng-show="!planChanging">Upgrade now</a>
<i class="fa fa-spinner fa-spin fa-3x" ng-show="planChanging"></i>
</div>
</div>
</div>
</div>
@ -91,7 +100,7 @@
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-8">
<button class="btn btn-large btn-success" type="submit" ng-click="createNewRepo" ng-disabled="newRepoForm.$invalid">Create Repository</button>
<button class="btn btn-large btn-success" type="submit" ng-disabled="newRepoForm.$invalid || (repo.is_public == '0' && planRequired)">Create Repository</button>
</div>
</div>
@ -179,3 +188,22 @@
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Modal message dialog -->
<div class="modal fade" id="couldnotsubscribeModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Cannot upgrade plan</h4>
</div>
<div class="modal-body">
Your current plan could not be upgraded. Please try again.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->