storage for org billing & signup

This commit is contained in:
Kyle Spearrin 2017-07-11 10:24:46 -04:00
parent 25536e10ef
commit ea4d772dda
10 changed files with 127 additions and 14 deletions

View File

@ -120,5 +120,14 @@ angular.module('bit')
annualPlanType: 'enterpriseAnnually', annualPlanType: 'enterpriseAnnually',
upgradeSortOrder: 3 upgradeSortOrder: 3
} }
},
storageGb: {
price: 0.33,
monthlyPrice: 0.50,
yearlyPrice: 4
},
premium: {
price: 10,
yearlyPrice: 10
} }
}); });

View File

@ -103,6 +103,17 @@
seats: org.Seats seats: org.Seats
}; };
$scope.storage = null;
if ($scope && org.MaxStorageGb) {
$scope.storage = {
currentGb: org.StorageGb || 0,
maxGb: org.MaxStorageGb,
currentName: org.StorageName || '0 GB'
};
$scope.storage.percentage = +($scope.storage.currentGb / $scope.storage.maxGb).toFixed(2);
}
$scope.subscription = null; $scope.subscription = null;
if (org.Subscription) { if (org.Subscription) {
$scope.subscription = { $scope.subscription = {

View File

@ -99,6 +99,32 @@
</button> </button>
</div> </div>
</div> </div>
<div class="box box-default" ng-if="storage">
<div class="box-header with-border">
<h3 class="box-title">Storage</h3>
</div>
<div class="box-body">
<p>
You plan has a total of {{storage.maxGb}} GB of encrypted file storage.
You are currently using {{storage.currentName}}.
</p>
<div class="progress" style="margin: 0;">
<div class="progress-bar progress-bar-info" role="progressbar"
aria-valuenow="{{storage.percentage}}" aria-valuemin="0" aria-valuemax="1"
style="min-width: 50px; width: {{storage.percentage}}%;">
{{storage.percentage}}%
</div>
</div>
</div>
<div class="box-footer">
<button type="button" class="btn btn-default btn-flat" ng-click="adjustStorage(true)">
Add Storage
</button>
<button type="button" class="btn btn-default btn-flat" ng-click="adjustStorage(false)">
Remove Storage
</button>
</div>
</div>
<div class="box box-default"> <div class="box box-default">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Payment Method</h3> <h3 class="box-title">Payment Method</h3>

View File

@ -217,6 +217,15 @@ angular
}); });
}; };
_service.updateProfilePremium = function (isPremium) {
return _service.getUserProfile().then(function (profile) {
if (profile) {
profile.premium = isPremium;
_userProfile = profile;
}
});
};
_service.isAuthenticated = function () { _service.isAuthenticated = function () {
return tokenService.getToken() !== null; return tokenService.getToken() !== null;
}; };

View File

@ -87,6 +87,17 @@
var i = 0; var i = 0;
$scope.storage = null;
if (billing && billing.MaxStorageGb) {
$scope.storage = {
currentGb: billing.StorageGb || 0,
maxGb: billing.MaxStorageGb,
currentName: billing.StorageName || '0 GB'
};
$scope.storage.percentage = +($scope.storage.currentGb / $scope.storage.maxGb).toFixed(2);
}
$scope.subscription = null; $scope.subscription = null;
if (billing && billing.Subscription) { if (billing && billing.Subscription) {
$scope.subscription = { $scope.subscription = {

View File

@ -4,21 +4,25 @@
.controller('settingsCreateOrganizationController', function ($scope, $state, apiService, cryptoService, .controller('settingsCreateOrganizationController', function ($scope, $state, apiService, cryptoService,
toastr, $analytics, authService, stripe, constants) { toastr, $analytics, authService, stripe, constants) {
$scope.plans = constants.plans; $scope.plans = constants.plans;
$scope.storageGb = constants.storageGb;
$scope.model = { $scope.model = {
plan: 'free', plan: 'free',
additionalSeats: 0, additionalSeats: 0,
interval: 'year', interval: 'year',
ownedBusiness: false ownedBusiness: false,
additionalStorageGb: null
}; };
$scope.totalPrice = function () { $scope.totalPrice = function () {
if ($scope.model.interval === 'month') { if ($scope.model.interval === 'month') {
return ($scope.model.additionalSeats || 0) * ($scope.plans[$scope.model.plan].monthlySeatPrice || 0) + return (($scope.model.additionalSeats || 0) * ($scope.plans[$scope.model.plan].monthlySeatPrice || 0)) +
(($scope.model.additionalStorageGb || 0) * $scope.storageGb.monthlyPrice) +
($scope.plans[$scope.model.plan].monthlyBasePrice || 0); ($scope.plans[$scope.model.plan].monthlyBasePrice || 0);
} }
else { else {
return ($scope.model.additionalSeats || 0) * ($scope.plans[$scope.model.plan].annualSeatPrice || 0) + return (($scope.model.additionalSeats || 0) * ($scope.plans[$scope.model.plan].annualSeatPrice || 0)) +
(($scope.model.additionalStorageGb || 0) * $scope.storageGb.yearlyPrice) +
($scope.plans[$scope.model.plan].annualBasePrice || 0); ($scope.plans[$scope.model.plan].annualBasePrice || 0);
} }
}; };
@ -65,6 +69,7 @@
key: shareKeyCt, key: shareKeyCt,
paymentToken: response.id, paymentToken: response.id,
additionalSeats: model.additionalSeats, additionalSeats: model.additionalSeats,
additionalStorageGb: model.additionalStorageGb,
billingEmail: model.billingEmail, billingEmail: model.billingEmail,
businessName: model.ownedBusiness ? model.businessName : null businessName: model.ownedBusiness ? model.businessName : null
}; };

View File

@ -1,15 +1,16 @@
angular angular
.module('bit.settings') .module('bit.settings')
.controller('settingsPremiumController', function ($scope, $state, apiService, toastr, $analytics, authService, stripe) { .controller('settingsPremiumController', function ($scope, $state, apiService, toastr, $analytics, authService, stripe,
constants) {
authService.getUserProfile().then(function (profile) { authService.getUserProfile().then(function (profile) {
if (profile.premium) { if (profile.premium) {
return $state.go('backend.user.settingsBilling'); return $state.go('backend.user.settingsBilling');
} }
}); });
$scope.storageGbPrice = 4; $scope.storageGbPrice = constants.storageGb.yearlyPrice;
$scope.premiumPrice = 10; $scope.premiumPrice = constants.premium.price;
$scope.model = { $scope.model = {
additionalStorageGb: null additionalStorageGb: null
@ -28,6 +29,8 @@
return apiService.accounts.postPremium(request).$promise; return apiService.accounts.postPremium(request).$promise;
}).then(function (result) { }).then(function (result) {
return authService.updateProfilePremium(true);
}).then(function () {
$analytics.eventTrack('Signed Up Premium'); $analytics.eventTrack('Signed Up Premium');
return authService.refreshAccessToken(); return authService.refreshAccessToken();
}).then(function () { }).then(function () {

View File

@ -8,7 +8,7 @@
</div> </div>
<div class="box-body"> <div class="box-body">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-5">
<dl> <dl>
<dt>Status</dt> <dt>Status</dt>
<dd style="text-transform: capitalize;">{{(subscription && subscription.status) || '-'}}</dd> <dd style="text-transform: capitalize;">{{(subscription && subscription.status) || '-'}}</dd>
@ -16,7 +16,7 @@
<dd>{{nextInvoice ? ((nextInvoice.date | date: format: mediumDate) + ', ' + (nextInvoice.amount | currency:'$')) : '-'}}</dd> <dd>{{nextInvoice ? ((nextInvoice.date | date: format: mediumDate) + ', ' + (nextInvoice.amount | currency:'$')) : '-'}}</dd>
</dl> </dl>
</div> </div>
<div class="col-md-6"> <div class="col-md-7">
<strong>Details</strong> <strong>Details</strong>
<div ng-show="loading"> <div ng-show="loading">
Loading... Loading...
@ -48,16 +48,20 @@
</button> </button>
</div> </div>
</div> </div>
<div class="box box-default"> <div class="box box-default" ng-if="storage">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Storage</h3> <h3 class="box-title">Storage</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
<p>You membership has a total of x GB of encrypted file storage. You are currently using y GB.</p> <p>
You membership has a total of {{storage.maxGb}} GB of encrypted file storage.
You are currently using {{storage.currentName}}.
</p>
<div class="progress" style="margin: 0;"> <div class="progress" style="margin: 0;">
<div class="progress-bar progress-bar-info" role="progressbar" <div class="progress-bar progress-bar-info" role="progressbar"
aria-valuenow="0.56" aria-valuemin="0" aria-valuemax="1" style="min-width: 2em; width: 56%;"> aria-valuenow="{{storage.percentage}}" aria-valuemin="0" aria-valuemax="1"
56% style="min-width: 50px; width: {{storage.percentage}}%;">
{{storage.percentage}}%
</div> </div>
</div> </div>
</div> </div>

View File

@ -75,6 +75,7 @@
<span>For personal users such as families &amp; friends.</span> <span>For personal users such as families &amp; friends.</span>
<span>- Add and share with up to 10 users (5 included with base price)</span> <span>- Add and share with up to 10 users (5 included with base price)</span>
<span>- Create unlimited collections</span> <span>- Create unlimited collections</span>
<span>- 1 GB encrypted file storage</span>
<span>- Priority customer support</span> <span>- Priority customer support</span>
<span>- 7 day free trial, cancel anytime</span> <span>- 7 day free trial, cancel anytime</span>
<span class="bottom-line"> <span class="bottom-line">
@ -90,6 +91,7 @@
<span>For businesses and other team organizations.</span> <span>For businesses and other team organizations.</span>
<span>- Add and share with unlimited users</span> <span>- Add and share with unlimited users</span>
<span>- Create unlimited collections</span> <span>- Create unlimited collections</span>
<span>- 1 GB encrypted file storage</span>
<span>- Priority customer support</span> <span>- Priority customer support</span>
<span>- 7 day free trial, cancel anytime</span> <span>- 7 day free trial, cancel anytime</span>
<span class="bottom-line"> <span class="bottom-line">
@ -105,6 +107,7 @@
<span>For businesses and other large organizations.</span> <span>For businesses and other large organizations.</span>
<span>- Add and share with unlimited users</span> <span>- Add and share with unlimited users</span>
<span>- Create unlimited collections</span> <span>- Create unlimited collections</span>
<span>- 1 GB encrypted file storage</span>
<span>- Control user access with groups</span> <span>- Control user access with groups</span>
<span>- Sync your users and groups from a directory (AD, Azure AD, GSuite, LDAP)</span> <span>- Sync your users and groups from a directory (AD, Azure AD, GSuite, LDAP)</span>
<span>- Priority customer support</span> <span>- Priority customer support</span>
@ -166,6 +169,27 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box box-default" ng-if="!plans[model.plan].noPayment">
<div class="box-header with-border">
<h3 class="box-title">Additional Storage</h3>
</div>
<div class="box-body">
<div class="form-group" show-errors style="margin: 0;">
<p>
Your plan comes with 1 GB of encrypted file storage. You can add additional
storage for {{storageGb.price | currency:"$":2}} per GB /month.
</p>
<div class="row">
<div class="col-md-4">
<label for="additionalStorage" class="sr-only">Storage</label>
<input type="number" id="additionalStorage" name="AdditionalStorageGb"
ng-model="model.additionalStorageGb" min="0" max="99" step="1" class="form-control"
placeholder="# of additional GB" api-field />
</div>
</div>
</div>
</div>
</div>
<div class="box box-default" ng-if="!plans[model.plan].noPayment"> <div class="box box-default" ng-if="!plans[model.plan].noPayment">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">Billing Summary</h3> <h3 class="box-title">Billing Summary</h3>
@ -187,6 +211,12 @@
&times;12 mo. = &times;12 mo. =
{{((model.additionalSeats || 0) * plans[model.plan].annualSeatPrice) | currency:"$":2}} /year {{((model.additionalSeats || 0) * plans[model.plan].annualSeatPrice) | currency:"$":2}} /year
</span> </span>
<span>
Additional storage:
{{model.additionalStorageGb || 0}} GB &times; {{storageGb.price | currency:"$":2}}
&times;12 mo. =
{{(model.additionalStorageGb || 0) * storageGb.yearlyPrice | currency:"$":2}} /year
</span>
</label> </label>
</div> </div>
<div class="radio radio-block" ng-if="model.plan !== 'personal'"> <div class="radio radio-block" ng-if="model.plan !== 'personal'">
@ -204,6 +234,11 @@
&times;{{plans[model.plan].monthlySeatPrice | currency:"$":2}} = &times;{{plans[model.plan].monthlySeatPrice | currency:"$":2}} =
{{((model.additionalSeats || 0) * plans[model.plan].monthlySeatPrice) | currency:"$":2}} /month {{((model.additionalSeats || 0) * plans[model.plan].monthlySeatPrice) | currency:"$":2}} /month
</span> </span>
<span>
Additional storage:
{{model.additionalStorageGb || 0}} GB &times; {{storageGb.monthlyPrice | currency:"$":2}} =
{{(model.additionalStorageGb || 0) * storageGb.monthlyPrice | currency:"$":2}} /month
</span>
</label> </label>
</div> </div>
</div> </div>

View File

@ -64,9 +64,9 @@
<h3 class="box-title">Billing Summary</h3> <h3 class="box-title">Billing Summary</h3>
</div> </div>
<div class="box-body"> <div class="box-body">
Premium Membership: Premium membership:
{{premiumPrice | currency:"$"}}<br /> {{premiumPrice | currency:"$"}}<br />
Additional Storage: Additional storage:
{{model.additionalStorageGb || 0}} GB &times; {{storageGbPrice | currency:"$"}} = {{model.additionalStorageGb || 0}} GB &times; {{storageGbPrice | currency:"$"}} =
{{(model.additionalStorageGb || 0) * storageGbPrice | currency:"$"}} {{(model.additionalStorageGb || 0) * storageGbPrice | currency:"$"}}
</div> </div>