Added subscription cancellation button to member page (#1683)

closes TryGhost/Ghost#12127

* Added cancel/continue button for individual subscriptions on member page

Co-authored-by: Peter Zimon <zimo@ghost.org>
This commit is contained in:
Rishabh Garg 2020-08-21 17:05:45 +05:30 committed by GitHub
parent 6f1d8cb99b
commit e41429b93b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 17 deletions

View File

@ -73,7 +73,9 @@
<section class="gh-member-stripe-info pa5 pb0 pt4 flex flex-column flex-row-ns items-start justify-between">
<div class="flex items-start w-100">
<div class="w-50 flex-auto mr8">
<h4 class="f8 fw6">Customer</h4>
<div class="gh-member-header-stripeinfo">
<h4 class="f6 fw6">Customer</h4>
</div>
<table class="gh-member-stripe-table">
<tr>
<td class="gh-member-stripe-label">Stripe customer ID</td>
@ -89,7 +91,7 @@
{{#if subscription.customer.name}}
{{subscription.customer.name}}
{{else}}
<span class="midlightgrey-l2">No name</span>
<span class="midgrey-d1">No name</span>
{{/if}}
</td>
</tr>
@ -99,7 +101,7 @@
{{#if subscription.customer.email}}
{{subscription.customer.email}}
{{else}}
<span class="midlightgrey-l2">No email</span>
<span class="midgrey-d1">No email</span>
{{/if}}
</td>
</tr>
@ -109,7 +111,7 @@
{{#if subscription.startDate}}
{{subscription.startDate}}
{{else}}
<span class="midlightgrey-l2">No data</span>
<span class="midgrey-d1">No data</span>
{{/if}}
</td>
</tr>
@ -117,7 +119,30 @@
</div>
<div class="w-50 flex-auto">
<h4 class="f8 fw6">Subscription</h4>
<div class="gh-member-header-stripeinfo">
<h4 class="f6 fw6">Subscription</h4>
{{#if (eq subscription.status "active")}}
{{#if subscription.cancelAtPeriodEnd}}
<GhTaskButton
@buttonText="Continue subscription"
@successText=""
@task={{this.continueSubscription}}
@taskArgs={{subscription.id}}
@class="gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="continue-subscription"
/>
{{else}}
<GhTaskButton
@buttonText="Cancel subscription"
@successText=""
@task={{this.cancelSubscription}}
@taskArgs={{subscription.id}}
@class="gh-btn gh-btn-icon gh-member-btn-cancelsub"
data-test-button="cancel-subscription"
/>
{{/if}}
{{/if}}
</div>
<table class="gh-member-stripe-table">
<tr>
<td class="gh-member-stripe-label">Stripe subscription ID</td>
@ -132,7 +157,7 @@
<td class="gh-member-stripe-label">Plan</td>
<td class="gh-member-stripe-data">
{{subscription.plan.nickname}}
<span class="midgrey">({{subscription.amount}}
<span class="midgrey-d1">({{subscription.amount}}
<span class="ttu">{{subscription.plan.currency}}</span>/{{subscription.plan.interval}})
</span>
</td>

View File

@ -3,12 +3,16 @@ import moment from 'moment';
import {computed} from '@ember/object';
import {gt} from '@ember/object/computed';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default Component.extend({
membersUtils: service(),
feature: service(),
config: service(),
mediaQueries: service(),
ghostPaths: service(),
ajax: service(),
store: service(),
// Allowed actions
setProperty: () => {},
@ -50,5 +54,31 @@ export default Component.extend({
setProperty(property, value) {
this.setProperty(property, value);
}
}
},
cancelSubscription: task(function* (subscriptionId) {
let url = this.get('ghostPaths.url').api('members', this.member.get('id'), 'subscriptions', subscriptionId);
let response = yield this.ajax.put(url, {
data: {
cancel_at_period_end: true
}
});
this.store.pushPayload('member', response);
return response;
}).drop(),
continueSubscription: task(function* (subscriptionId) {
let url = this.get('ghostPaths.url').api('members', this.member.get('id'), 'subscriptions', subscriptionId);
let response = yield this.ajax.put(url, {
data: {
cancel_at_period_end: false
}
});
this.store.pushPayload('member', response);
return response;
}).drop()
});

View File

@ -207,11 +207,6 @@ p.gh-members-list-email {
border-bottom-right-radius: 0px !important;
}
.gh-members-not-found-for-label {
}
/* .members-header .gh-member */
@media (max-width: 1100px) {
.gh-members-chart-summary-data {
@ -379,6 +374,18 @@ textarea.gh-member-details-textarea {
height: 18px;
}
.gh-member-header-stripeinfo {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 24px;
}
.gh-member-header-stripeinfo h4 {
margin: 0 12px 0 0;
padding: 0;
}
.gh-member-stripe-info {
border-bottom: 1px solid var(--whitegrey);
}
@ -389,7 +396,7 @@ textarea.gh-member-details-textarea {
.gh-member-stripe-table {
width: 100%;
margin: 10px 0 12px;
margin: 6px 0 12px;
}
.gh-member-stripe-table td {
@ -417,15 +424,40 @@ textarea.gh-member-details-textarea {
display: inline-block;
background: var(--lightgrey-d1);
border-radius: 4px;
padding: 1px 6px;
margin: -2px 0 -2px -6px;
padding: 0px 5px;
margin: -2px 0 -2px -5px;
color: var(--darkgrey);
font-size: 1.4rem;
font-weight: 500;
font-size: 1.3rem;
font-weight: 400;
}
.gh-member-stripe-status {
display: inline-block;
text-transform: capitalize;
margin-right: 6px;
}
.gh-member-btn-cancelsub span,
.gh-member-btn-contsub span {
height: 25px;
line-height: 25px;
}
.gh-member-btn-contsub {
border-color: var(--blue);
box-shadow: none;
}
.gh-member-btn-contsub:hover {
border-color: color-mod(var(--blue) l(-7%) saturation(-10%));
}
.gh-member-btn-contsub span {
color: var(--blue);
}
.gh-member-btn-contsub:hover span {
color: color-mod(var(--blue) l(-7%) saturation(-10%));
}
.gh-member-settings-primary {