Added Tips & Donations one-off payments

no issue

Give your audience a simple way to support your work with one-time payments, no membership required.

- cleaned up `tipsAndDonations` labs flag
This commit is contained in:
Kevin Ansfield 2024-09-03 13:57:30 +01:00
parent 3744caa950
commit 1bc34f7227
14 changed files with 9 additions and 36 deletions

View File

@ -1,7 +1,6 @@
import GhostLogo from '../assets/images/orb-pink.png';
import React, {useEffect, useRef} from 'react';
import clsx from 'clsx';
import useFeatureFlag from '../hooks/useFeatureFlag';
import {Button, Icon, SettingNavItem, SettingNavItemProps, SettingNavSection, TextField, useFocusContext} from '@tryghost/admin-x-design-system';
import {searchKeywords as advancedSearchKeywords} from './settings/advanced/AdvancedSettings';
import {checkStripeEnabled, getSettingValues} from '@tryghost/admin-x-framework/api/settings';
@ -35,7 +34,6 @@ const Sidebar: React.FC = () => {
const {updateRoute} = useRouting();
const searchInputRef = useRef<HTMLInputElement | null>(null);
const {isAnyTextFieldFocused} = useFocusContext();
// const hasOffersLabs = useFeatureFlag('adminXOffers');
// Focus in on search field when pressing "/"
useEffect(() => {
@ -110,8 +108,6 @@ const Sidebar: React.FC = () => {
}
};
const hasTipsAndDonations = useFeatureFlag('tipsAndDonations');
const updateSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setFilter(e.target.value);
@ -186,7 +182,7 @@ const Sidebar: React.FC = () => {
<NavItem icon='heart' keywords={growthSearchKeywords.recommendations} navid='recommendations' title="Recommendations" onClick={handleSectionClick} />
<NavItem icon='emailfield' keywords={growthSearchKeywords.embedSignupForm} navid='embed-signup-form' title="Embeddable signup form" onClick={handleSectionClick} />
{hasStripeEnabled && <NavItem icon='discount' keywords={growthSearchKeywords.offers} navid='offers' title="Offers" onClick={handleSectionClick} />}
{hasTipsAndDonations && hasStripeEnabled && <NavItem icon='piggybank' keywords={growthSearchKeywords.tips} navid='tips-and-donations' title="Tips & donations" onClick={handleSectionClick} />}
{hasStripeEnabled && <NavItem icon='piggybank' keywords={growthSearchKeywords.tips} navid='tips-and-donations' title="Tips & donations" onClick={handleSectionClick} />}
</SettingNavSection>
<SettingNavSection isVisible={checkVisible(Object.values(emailSearchKeywords).flat())} title="Email newsletter">

View File

@ -39,10 +39,6 @@ const features = [{
title: 'Import Member Tier',
description: 'Enables tier to be specified when importing members',
flag: 'importMemberTier'
},{
title: 'Tips & donations',
description: 'Enables publishers to collect one-time payments',
flag: 'tipsAndDonations'
},{
title: 'AdminX Demo',
description: 'Adds a navigation link to the AdminX demo app',

View File

@ -8,7 +8,6 @@ import {useGlobalData} from '../../../providers/GlobalDataProvider';
const EmailNotificationsInputs: React.FC<{ user: User; setUserData: (user: User) => void; }> = ({user, setUserData}) => {
const {config, settings} = useGlobalData();
const hasWebmentions = useFeatureFlag('webmentions');
const hasTipsAndDonations = useFeatureFlag('tipsAndDonations');
const hasStripeEnabled = checkStripeEnabled(settings || [], config || {});
return (
@ -77,7 +76,7 @@ const EmailNotificationsInputs: React.FC<{ user: User; setUserData: (user: User)
setUserData?.({...user, milestone_notifications: e.target.checked});
}}
/>
{hasTipsAndDonations && hasStripeEnabled && <Toggle
{hasStripeEnabled && <Toggle
checked={user.donation_notifications}
direction='rtl'
hint='Every time you receive a one-time payment'

View File

@ -4,7 +4,6 @@ import React from 'react';
import Recommendations from './Recommendations';
import SearchableSection from '../../SearchableSection';
import TipsAndDonations from './TipsAndDonations';
import useFeatureFlag from '../../../hooks/useFeatureFlag';
import {checkStripeEnabled} from '@tryghost/admin-x-framework/api/settings';
import {useGlobalData} from '../../providers/GlobalDataProvider';
@ -16,7 +15,6 @@ export const searchKeywords = {
};
const GrowthSettings: React.FC = () => {
const hasTipsAndDonations = useFeatureFlag('tipsAndDonations');
const {config, settings} = useGlobalData();
const hasStripeEnabled = checkStripeEnabled(settings || [], config || {});
@ -25,7 +23,7 @@ const GrowthSettings: React.FC = () => {
<Recommendations keywords={searchKeywords.recommendations} />
<EmbedSignupForm keywords={searchKeywords.embedSignupForm} />
{hasStripeEnabled && <Offers keywords={searchKeywords.offers} />}
{hasTipsAndDonations && hasStripeEnabled && <TipsAndDonations keywords={searchKeywords.tips} />}
{hasStripeEnabled && <TipsAndDonations keywords={searchKeywords.tips} />}
</SearchableSection>
);
};

View File

@ -1,7 +1,7 @@
import {StaffTokenResponseType} from '@tryghost/admin-x-framework/api/staffToken';
import {expect, test} from '@playwright/test';
import {globalDataRequests} from '../../../utils/acceptance';
import {mockApi, responseFixtures, settingsWithStripe, testUrlValidation, toggleLabsFlag} from '@tryghost/admin-x-framework/test/acceptance';
import {mockApi, responseFixtures, settingsWithStripe, testUrlValidation} from '@tryghost/admin-x-framework/test/acceptance';
test.describe('User profile', async () => {
test('Supports editing user profiles', async ({page}) => {
@ -292,8 +292,6 @@ test.describe('User profile', async () => {
});
test('Shows donation notification option when Stripe enabled', async ({page}) => {
toggleLabsFlag('tipsAndDonations', true);
const userToEdit = responseFixtures.users.users.find(user => user.email === 'administrator@test.com')!;
const {lastApiRequests} = await mockApi({page, requests: {
@ -337,8 +335,6 @@ test.describe('User profile', async () => {
});
test('Hides donation notification option when Stripe disabled', async ({page}) => {
toggleLabsFlag('tipsAndDonations', true);
await mockApi({page, requests: {
...globalDataRequests,
browseUsers: {method: 'GET', path: '/users/?limit=100&include=roles', response: responseFixtures.users}

View File

@ -1,12 +1,8 @@
import {expect, test} from '@playwright/test';
import {globalDataRequests} from '../../utils/acceptance';
import {mockApi, settingsWithStripe, toggleLabsFlag} from '@tryghost/admin-x-framework/test/acceptance';
import {mockApi, settingsWithStripe} from '@tryghost/admin-x-framework/test/acceptance';
test.describe('Tips and donations', () => {
test.beforeEach(async () => {
toggleLabsFlag('tipsAndDonations', true);
});
test('Is not shown when Stripe is disabled', async ({page}) => {
await mockApi({page, requests: {...globalDataRequests}});
await page.goto('/');

View File

@ -352,7 +352,6 @@
</td>
</tr>
{{/if}}
{{#if (feature "tipsAndDonations")}}
<tr>
<td colspan="2"><hr class="gh-portal-links-group-divider" /></td>
</tr>
@ -389,7 +388,6 @@
</div>
</td>
</tr>
{{/if}}
<tr>
<td colspan="2"><hr class="gh-portal-links-group-divider" /></td>
</tr>

View File

@ -318,7 +318,7 @@ export default class KoenigLexicalEditor extends Component {
};
const donationLink = () => {
if (this.feature.tipsAndDonations && this.settings.donationsEnabled) {
if (this.settings.donationsEnabled) {
return [{
label: 'Tips and donations',
value: '#/portal/support'

View File

@ -72,7 +72,6 @@ export default class FeatureService extends Service {
@feature('mailEvents') mailEvents;
@feature('collectionsCard') collectionsCard;
@feature('importMemberTier') importMemberTier;
@feature('tipsAndDonations') tipsAndDonations;
@feature('lexicalIndicators') lexicalIndicators;
@feature('adminXDemo') adminXDemo;
@feature('ActivityPub') ActivityPub;

View File

@ -9,8 +9,7 @@ describe('Unit | Utility | event-type-utils', function () {
emailTrackClicks: true
};
const feature = {
audienceFeedback: true,
tipsAndDonations: true
audienceFeedback: true
};
const hiddenEvents = [];
@ -56,8 +55,7 @@ describe('Unit | Utility | event-type-utils', function () {
emailTrackClicks: false
};
const feature = {
audienceFeedback: false,
tipsAndDonations: false
audienceFeedback: false
};
const hiddenEvents = [];

View File

@ -46,7 +46,7 @@ function finaliseStructuredData(meta) {
function getMembersHelper(data, frontendKey) {
// Do not load Portal if both Memberships and Tips & Donations are disabled
if (!settingsCache.get('members_enabled') && !(settingsCache.get('donations_enabled') && labs.isSet('tipsAndDonations'))) {
if (!settingsCache.get('members_enabled') && !settingsCache.get('donations_enabled')) {
return '';
}

View File

@ -41,7 +41,6 @@ const ALPHA_FEATURES = [
'emailCustomization',
'mailEvents',
'collectionsCard',
'tipsAndDonations',
'importMemberTier',
'lexicalIndicators',
'adminXDemo',

View File

@ -31,7 +31,6 @@ Object {
"outboundLinkTagging": true,
"stripeAutomaticTax": true,
"themeErrorsNotification": true,
"tipsAndDonations": true,
"urlCache": true,
"webmentions": true,
},

View File

@ -125,7 +125,6 @@ const enableLabs = async (page) => {
await section.getByRole('tab', {name: 'Alpha features'}).click();
await section.getByLabel('Webmentions').click();
await section.getByLabel('Tips & donations').click();
await page.getByTestId('exit-settings').click();
};