mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-27 10:42:45 +03:00
✨ Added referrals invite notification (#16187)
no issue - Ghost users that make >= $100 MRR will see a dismissible notification that invites them to the Ghost Referral program - Only applies to Admin and Owner users and when Stripe is setup and connected in live mode - By saving a `referralInviteDismissed` property to the users' `accessibility` JSON object we can determine if the notification has been dismissed and won't show it again - Added new `gh-referral-invite` component
This commit is contained in:
parent
63d216c321
commit
488d9bb135
@ -1,11 +1,13 @@
|
||||
<div class="gh-nav-bottom">
|
||||
{{#if this.hasThemeErrors}}
|
||||
<button type="button" class="gh-theme-error-toast" {{on "click" (fn this.openThemeErrors null)}}>
|
||||
<span class="gh-notification-title">Your theme contains errors</span>
|
||||
<span class="gh-theme-error-p">Some functionality on your site may be limited →</span>
|
||||
<button type="button" class="gh-footer-toast gh-theme-error-toast" {{on "click" (fn this.openThemeErrors null)}}>
|
||||
<span class="gh-footer-toast-title gh-notification-title">Your theme contains errors</span>
|
||||
<span class="gh-footer-toast-p">Some functionality on your site may be limited →</span>
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
<GhReferralInvite @hasThemeErrors={{this.hasThemeErrors}} />
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="pe-all">
|
||||
<GhBasicDropdown @horizontalPosition="left" @verticalPosition="above" @calculatePosition={{this.userDropdownPosition}} as |dropdown|>
|
||||
|
10
ghost/admin/app/components/gh-referral-invite.hbs
Normal file
10
ghost/admin/app/components/gh-referral-invite.hbs
Normal file
@ -0,0 +1,10 @@
|
||||
{{#if this.showReferralInvite}}
|
||||
<div class="gh-referral-toast">
|
||||
<button class="gh-referral-toast-close" type="button" {{on "click" this.dismissReferralInvite}}>×</button>
|
||||
<a href="https://referrals.ghost.org/?ref=admin" target="_blank" rel="noopener noreferrer">
|
||||
<strong>You qualify for our invite-only referral program.</strong>
|
||||
<p class="gh-footer-toast-p">Refer people to Ghost and earn a <strong>30% share</strong> of the subscription revenue, every single month.</p>
|
||||
<div class="gh-btn gh-btn-black gh-referral-toast-button" type="button"><span>Find out more →</span></div>
|
||||
</a>
|
||||
</div>
|
||||
{{/if}}
|
68
ghost/admin/app/components/gh-referral-invite.js
Normal file
68
ghost/admin/app/components/gh-referral-invite.js
Normal file
@ -0,0 +1,68 @@
|
||||
import Component from '@glimmer/component';
|
||||
import envConfig from 'ghost-admin/config/environment';
|
||||
import moment from 'moment-timezone';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency';
|
||||
|
||||
export default class GhReferralInvite extends Component {
|
||||
@service session;
|
||||
@service dashboardStats;
|
||||
@service feature;
|
||||
@service membersUtils;
|
||||
@service settings;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.loadCurrentMRR.perform();
|
||||
}
|
||||
|
||||
get isAdminOrOwner() {
|
||||
return this.session.user.isAdmin;
|
||||
}
|
||||
|
||||
get isReferralNotificationNotDismissed() {
|
||||
return !this.feature.accessibility.referralInviteDismissed;
|
||||
}
|
||||
|
||||
get stripeLiveModeEnabled() {
|
||||
// allow testing mode when not in a production environment
|
||||
const isDevModeStripeEnabled = envConfig.environment !== 'production' && this.membersUtils.isStripeEnabled;
|
||||
const isLiveEnabled = this.settings.stripeConnectLivemode;
|
||||
return isDevModeStripeEnabled || isLiveEnabled;
|
||||
}
|
||||
|
||||
get hasReachedMRR() {
|
||||
return this.dashboardStats.currentMRR / 100 >= 100;
|
||||
}
|
||||
|
||||
get showReferralInvite() {
|
||||
// Conditions to see the referral invite
|
||||
// 1. Needs to be Owner or Admin
|
||||
// 2. Stripe is setup and enabled in live mode
|
||||
// 3. MRR is > $100
|
||||
// 4. Notification has not yet been dismissed by the user
|
||||
return !this.args.hasThemeErrors && this.isAdminOrOwner && this.isReferralNotificationNotDismissed && this.stripeLiveModeEnabled && this.hasReachedMRR;
|
||||
}
|
||||
|
||||
@task
|
||||
*loadCurrentMRR() {
|
||||
if (this.isAdminOrOwnern) {
|
||||
try {
|
||||
yield this.dashboardStats.loadMrrStats();
|
||||
} catch (error) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
dismissReferralInvite(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (!this.feature.referralInviteDismissed) {
|
||||
this.feature.referralInviteDismissed = moment().tz(this.settings.timezone);
|
||||
}
|
||||
}
|
||||
}
|
@ -55,6 +55,9 @@ export default class FeatureService extends Service {
|
||||
@feature('nightShift', {user: true, onChange: '_setAdminTheme'})
|
||||
nightShift;
|
||||
|
||||
// user-specific referral invitation
|
||||
@feature('referralInviteDismissed', {user: true}) referralInviteDismissed;
|
||||
|
||||
// labs flags
|
||||
@feature('urlCache') urlCache;
|
||||
@feature('beforeAfterCard') beforeAfterCard;
|
||||
|
@ -810,6 +810,10 @@ input:focus,
|
||||
background: color-mod(var(--dark-main-bg-color) l(+2%));
|
||||
}
|
||||
|
||||
.gh-referral-toast-close:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nightshift-toggle {
|
||||
background: var(--lightgrey);
|
||||
}
|
||||
@ -1486,4 +1490,4 @@ kbd {
|
||||
|
||||
.gh-mention-your-post-link {
|
||||
color: var(--black);
|
||||
}
|
||||
}
|
||||
|
@ -2149,8 +2149,8 @@ section.gh-ds h2 {
|
||||
}
|
||||
|
||||
|
||||
/* Theme error toast and modal */
|
||||
.gh-theme-error-toast {
|
||||
/* Footer toast in navbar */
|
||||
.gh-footer-toast {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 1.3rem;
|
||||
@ -2159,10 +2159,87 @@ section.gh-ds h2 {
|
||||
padding: 20px;
|
||||
margin-bottom: 32px;
|
||||
color: #fff;
|
||||
background: var(--red);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.gh-theme-error-toast .gh-notification-title {
|
||||
.gh-footer-toast-title.gh-notification-title {
|
||||
margin: 0 0 6px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Theme error toast and modal */
|
||||
.gh-theme-error-toast {
|
||||
background: var(--red);
|
||||
}
|
||||
|
||||
/* Ghost Referrals invite toast */
|
||||
.gh-referral-toast {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 25px;
|
||||
margin-bottom: 50px;
|
||||
color: var(--black);
|
||||
text-decoration: none;
|
||||
background: var(--white);
|
||||
border-radius: 10px;
|
||||
box-shadow: rgb(75 225 226 / 28%) -7px -6px 42px 8px, rgb(202 103 255 / 32%) 7px 6px 42px 8px;
|
||||
transition: all 0.6s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gh-referral-toast a {
|
||||
color: var(--black);
|
||||
}
|
||||
|
||||
.gh-referral-toast:hover {
|
||||
transform: translateY(-2px) scale(1.01);
|
||||
box-shadow: rgb(75 225 226 / 38%) -7px -4px 42px 10px, rgb(202 103 255 / 42%) 7px 8px 42px 10px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.gh-referral-toast-close {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 10px;
|
||||
padding: 5px;
|
||||
color: #ddd;
|
||||
font-size: 2.2rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.gh-referral-toast-close:hover {
|
||||
color: #15171A;
|
||||
}
|
||||
|
||||
.gh-referral-toast a > strong {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.7rem;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
.gh-referral-toast a > p {
|
||||
margin: 0;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.35em;
|
||||
letter-spacing: -0.015em;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.gh-referral-toast a > p strong {
|
||||
color: #ff247d;
|
||||
}
|
||||
|
||||
.gh-referral-toast-button {
|
||||
margin-top: 20px;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.gh-referral-toast-button span {
|
||||
padding: 0 12px;
|
||||
font-size: 1.4rem;
|
||||
text-align-last: center;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user