mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Added logic to load Portal when Tips & Donations are enabled (#17634)
closes https://github.com/TryGhost/Product/issues/3661 - until now, Portal was not loaded if members were disabled. With the introduction of Tips & Donations, signed-off readers can also make payments, using the Portal link /#/portal/support. - now, Portal is loaded when Tips & Donations are enabled, even if Memberships are disabled - depending on the member signup access, the "sign in" / "subscribe" Portal buttons are hidden (both hidden if none, signup hidden if invite-only) - for any other signup / signin Portal links (e.g., added by the theme, or added via a Post/Page), a new popup informs the reader as such when Memberships are disabled: "Memberships unavailable, contact the site owner for access".
This commit is contained in:
parent
cd013356f9
commit
b95c8275f2
11 changed files with 244 additions and 62 deletions
|
@ -9,7 +9,7 @@ import {ReactComponent as ButtonIcon3} from '../images/icons/button-icon-3.svg';
|
|||
import {ReactComponent as ButtonIcon4} from '../images/icons/button-icon-4.svg';
|
||||
import {ReactComponent as ButtonIcon5} from '../images/icons/button-icon-5.svg';
|
||||
import TriggerButtonStyle from './TriggerButton.styles';
|
||||
import {isInviteOnlySite} from '../utils/helpers';
|
||||
import {isInviteOnlySite, isSigninAllowed} from '../utils/helpers';
|
||||
import {hasMode} from '../utils/check-mode';
|
||||
|
||||
const ICON_MAPPING = {
|
||||
|
@ -164,12 +164,21 @@ class TriggerButtonContent extends React.Component {
|
|||
|
||||
onToggle() {
|
||||
const {showPopup, member, site} = this.context;
|
||||
|
||||
if (showPopup) {
|
||||
this.context.onAction('closePopup');
|
||||
} else {
|
||||
const loggedOutPage = isInviteOnlySite({site}) ? 'signin' : 'signup';
|
||||
const page = member ? 'accountHome' : loggedOutPage;
|
||||
return;
|
||||
}
|
||||
|
||||
if (member) {
|
||||
this.context.onAction('openPopup', {page: 'accountHome'});
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSigninAllowed({site})) {
|
||||
const page = isInviteOnlySite({site}) ? 'signin' : 'signup';
|
||||
this.context.onAction('openPopup', {page});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,10 +249,11 @@ export default class TriggerButton extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {portal_button: portalButton} = this.context.site;
|
||||
const site = this.context.site;
|
||||
const {portal_button: portalButton} = site;
|
||||
const {showPopup} = this.context;
|
||||
|
||||
if (!portalButton || hasMode(['offerPreview'])) {
|
||||
if (!portalButton || !isSigninAllowed({site}) || hasMode(['offerPreview'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,18 @@ import {getSupportAddress} from '../../../utils/helpers';
|
|||
|
||||
import AccountFooter from './components/AccountFooter';
|
||||
import AccountMain from './components/AccountMain';
|
||||
import {isSigninAllowed} from '../../../utils/helpers';
|
||||
|
||||
export default class AccountHomePage extends React.Component {
|
||||
static contextType = AppContext;
|
||||
|
||||
componentDidMount() {
|
||||
const {member} = this.context;
|
||||
const {member, site} = this.context;
|
||||
|
||||
if (!isSigninAllowed({site})) {
|
||||
this.context.onAction('signout');
|
||||
}
|
||||
|
||||
if (!member) {
|
||||
this.context.onAction('switchPage', {
|
||||
page: 'signin',
|
||||
|
@ -31,6 +37,9 @@ export default class AccountHomePage extends React.Component {
|
|||
if (!member) {
|
||||
return null;
|
||||
}
|
||||
if (!isSigninAllowed({site})) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className='gh-portal-account-wrapper'>
|
||||
<AccountMain />
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import AppContext from '../../../../AppContext';
|
||||
import ActionButton from '../../../common/ActionButton';
|
||||
import {hasOnlyFreePlan} from '../../../../utils/helpers';
|
||||
import {isSignupAllowed} from '../../../../utils/helpers';
|
||||
import {useContext} from 'react';
|
||||
|
||||
const SubscribeButton = () => {
|
||||
const {site, action, brandColor, onAction, t} = useContext(AppContext);
|
||||
const {is_stripe_configured: isStripeConfigured} = site;
|
||||
|
||||
if (!isStripeConfigured || hasOnlyFreePlan({site})) {
|
||||
if (!isSignupAllowed({site})) {
|
||||
return null;
|
||||
}
|
||||
const isRunning = ['checkoutPlan:running'].includes(action);
|
||||
|
|
|
@ -5,6 +5,8 @@ import CloseButton from '../common/CloseButton';
|
|||
import AppContext from '../../AppContext';
|
||||
import InputForm from '../common/InputForm';
|
||||
import {ValidateInputForm} from '../../utils/form';
|
||||
import {isSigninAllowed} from '../../utils/helpers';
|
||||
import {ReactComponent as InvitationIcon} from '../../images/icons/invitation.svg';
|
||||
|
||||
export default class SigninPage extends React.Component {
|
||||
static contextType = AppContext;
|
||||
|
@ -116,6 +118,23 @@ export default class SigninPage extends React.Component {
|
|||
}
|
||||
|
||||
renderForm() {
|
||||
const {site, t} = this.context;
|
||||
|
||||
if (!isSigninAllowed({site})) {
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
<p
|
||||
className='gh-portal-members-disabled-notification'
|
||||
data-testid="members-disabled-notification-text"
|
||||
>
|
||||
{t('Memberships unavailable, contact the owner for access.')}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
|
@ -125,32 +144,52 @@ export default class SigninPage extends React.Component {
|
|||
onKeyDown={(e, field) => this.onKeyDown(e, field)}
|
||||
/>
|
||||
</div>
|
||||
<footer className='gh-portal-signin-footer'>
|
||||
{this.renderSubmitButton()}
|
||||
{this.renderSignupMessage()}
|
||||
</footer>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
renderSiteLogo() {
|
||||
const siteLogo = this.context.site.icon;
|
||||
renderSiteIcon() {
|
||||
const iconStyle = {};
|
||||
const {site} = this.context;
|
||||
const siteIcon = site.icon;
|
||||
|
||||
const logoStyle = {};
|
||||
|
||||
if (siteLogo) {
|
||||
logoStyle.backgroundImage = `url(${siteLogo})`;
|
||||
if (siteIcon) {
|
||||
iconStyle.backgroundImage = `url(${siteIcon})`;
|
||||
return (
|
||||
<img className='gh-portal-signup-logo' src={siteLogo} alt={this.context.site.title} />
|
||||
<img className='gh-portal-signup-logo' src={siteIcon} alt={this.context.site.title} />
|
||||
);
|
||||
} else if (!isSigninAllowed({site})) {
|
||||
return (
|
||||
<InvitationIcon className='gh-portal-icon gh-portal-icon-invitation' />
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
renderFormHeader() {
|
||||
// const siteTitle = this.context.site.title || 'Site Title';
|
||||
const {t} = this.context;
|
||||
renderSiteTitle() {
|
||||
const {site, t} = this.context;
|
||||
const siteTitle = site.title;
|
||||
|
||||
if (!isSigninAllowed({site})) {
|
||||
return (
|
||||
<h1 className='gh-portal-main-title'>{siteTitle}</h1>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<h1 className='gh-portal-main-title'>{t('Sign in')}</h1>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderFormHeader() {
|
||||
return (
|
||||
<header className='gh-portal-signin-header'>
|
||||
{this.renderSiteLogo()}
|
||||
<h1 className="gh-portal-main-title">{t('Sign in')}</h1>
|
||||
{this.renderSiteIcon()}
|
||||
{this.renderSiteTitle()}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
@ -158,19 +197,12 @@ export default class SigninPage extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<>
|
||||
{/* <div className='gh-portal-back-sitetitle'>
|
||||
<SiteTitleBackButton />
|
||||
</div> */}
|
||||
<CloseButton />
|
||||
<div className='gh-portal-logged-out-form-container'>
|
||||
<div className='gh-portal-content signin'>
|
||||
{this.renderFormHeader()}
|
||||
{this.renderForm()}
|
||||
</div>
|
||||
<footer className='gh-portal-signin-footer'>
|
||||
{this.renderSubmitButton()}
|
||||
{this.renderSignupMessage()}
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
import {render, fireEvent} from '../../utils/test-utils';
|
||||
import {render, fireEvent, getByTestId} from '../../utils/test-utils';
|
||||
import SigninPage from './SigninPage';
|
||||
import {getSiteData} from '../../utils/fixtures-generator';
|
||||
|
||||
const setup = () => {
|
||||
const setup = (overrides) => {
|
||||
const {mockOnActionFn, ...utils} = render(
|
||||
<SigninPage />,
|
||||
{
|
||||
overrideContext: {
|
||||
member: null
|
||||
member: null,
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
);
|
||||
const emailInput = utils.getByLabelText(/email/i);
|
||||
const submitButton = utils.queryByRole('button', {name: 'Continue'});
|
||||
const signupButton = utils.queryByRole('button', {name: 'Sign up'});
|
||||
|
||||
let emailInput;
|
||||
let submitButton;
|
||||
let signupButton;
|
||||
|
||||
try {
|
||||
emailInput = utils.getByLabelText(/email/i);
|
||||
submitButton = utils.queryByRole('button', {name: 'Continue'});
|
||||
signupButton = utils.queryByRole('button', {name: 'Sign up'});
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return {
|
||||
emailInput,
|
||||
submitButton,
|
||||
|
@ -47,4 +59,17 @@ describe('SigninPage', () => {
|
|||
fireEvent.click(signupButton);
|
||||
expect(mockOnActionFn).toHaveBeenCalledWith('switchPage', {page: 'signup'});
|
||||
});
|
||||
|
||||
describe('when members are disabled', () => {
|
||||
test('renders an informative message', () => {
|
||||
setup({
|
||||
site: getSiteData({
|
||||
membersSignupAccess: 'none'
|
||||
})
|
||||
});
|
||||
|
||||
const message = getByTestId(document.body, 'members-disabled-notification-text');
|
||||
expect(message).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ import NewsletterSelectionPage from './NewsletterSelectionPage';
|
|||
import ProductsSection from '../common/ProductsSection';
|
||||
import InputForm from '../common/InputForm';
|
||||
import {ValidateInputForm} from '../../utils/form';
|
||||
import {getSiteProducts, getSitePrices, hasOnlyFreePlan, isInviteOnlySite, freeHasBenefitsOrDescription, hasOnlyFreeProduct, getFreeProductBenefits, getFreeTierDescription, hasFreeProductPrice, hasMultipleNewsletters, hasFreeTrialTier} from '../../utils/helpers';
|
||||
import {getSiteProducts, getSitePrices, hasOnlyFreePlan, isInviteOnlySite, freeHasBenefitsOrDescription, hasOnlyFreeProduct, getFreeProductBenefits, getFreeTierDescription, hasFreeProductPrice, hasMultipleNewsletters, hasFreeTrialTier, isSignupAllowed} from '../../utils/helpers';
|
||||
import {ReactComponent as InvitationIcon} from '../../images/icons/invitation.svg';
|
||||
|
||||
export const SignupPageStyles = `
|
||||
|
@ -171,7 +171,7 @@ footer.gh-portal-signup-footer.invite-only .gh-portal-signup-message {
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
.gh-portal-invite-only-notification {
|
||||
.gh-portal-invite-only-notification, .gh-portal-members-disabled-notification {
|
||||
margin: 8px 32px 24px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
|
@ -670,6 +670,21 @@ class SignupPage extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (!isSignupAllowed({site})) {
|
||||
return (
|
||||
<section>
|
||||
<div className='gh-portal-section'>
|
||||
<p
|
||||
className='gh-portal-members-disabled-notification'
|
||||
data-testid="members-disabled-notification-text"
|
||||
>
|
||||
{t('Memberships unavailable, contact the owner for access.')}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
const freeBenefits = getFreeProductBenefits({site});
|
||||
const freeDescription = getFreeTierDescription({site});
|
||||
const showOnlyFree = pageQuery === 'free' && hasFreeProductPrice({site});
|
||||
|
@ -716,22 +731,22 @@ class SignupPage extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderSiteLogo() {
|
||||
renderSiteIcon() {
|
||||
const {site, pageQuery} = this.context;
|
||||
const siteIcon = site.icon;
|
||||
|
||||
const siteLogo = site.icon;
|
||||
|
||||
const logoStyle = {};
|
||||
|
||||
if (siteLogo) {
|
||||
logoStyle.backgroundImage = `url(${siteLogo})`;
|
||||
if (siteIcon) {
|
||||
return (
|
||||
<img className='gh-portal-signup-logo' src={siteLogo} alt={site.title} />
|
||||
<img className='gh-portal-signup-logo' src={siteIcon} alt={site.title} />
|
||||
);
|
||||
} else if (isInviteOnlySite({site, pageQuery})) {
|
||||
return (
|
||||
<InvitationIcon className='gh-portal-icon gh-portal-icon-invitation' />
|
||||
);
|
||||
} else if (!isSignupAllowed({site})) {
|
||||
return (
|
||||
<InvitationIcon className='gh-portal-icon gh-portal-icon-invitation' />
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -741,7 +756,7 @@ class SignupPage extends React.Component {
|
|||
const siteTitle = site.title || '';
|
||||
return (
|
||||
<header className='gh-portal-signup-header'>
|
||||
{this.renderSiteLogo()}
|
||||
{this.renderSiteIcon()}
|
||||
<h1 className="gh-portal-main-title" data-testid='site-title-text'>{siteTitle}</h1>
|
||||
</header>
|
||||
);
|
||||
|
@ -794,10 +809,6 @@ class SignupPage extends React.Component {
|
|||
{this.renderFormHeader()}
|
||||
{this.renderForm()}
|
||||
</div>
|
||||
{/* <footer className={'gh-portal-signup-footer gh-portal-logged-out-form-container ' + footerClass}>
|
||||
{this.renderSubmitButton()}
|
||||
{this.renderLoginMessage()}
|
||||
</footer> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import SignupPage from './SignupPage';
|
||||
import {getFreeProduct, getProductData, getSiteData} from '../../utils/fixtures-generator';
|
||||
import {render, fireEvent} from '../../utils/test-utils';
|
||||
import {render, fireEvent, getByTestId} from '../../utils/test-utils';
|
||||
|
||||
const setup = (overrides) => {
|
||||
const {mockOnActionFn, ...utils} = render(
|
||||
|
@ -12,12 +12,25 @@ const setup = (overrides) => {
|
|||
}
|
||||
}
|
||||
);
|
||||
const emailInput = utils.getByLabelText(/email/i);
|
||||
const nameInput = utils.getByLabelText(/name/i);
|
||||
const submitButton = utils.queryByRole('button', {name: 'Continue'});
|
||||
const chooseButton = utils.queryAllByRole('button', {name: 'Choose'});
|
||||
const signinButton = utils.queryByRole('button', {name: 'Sign in'});
|
||||
const freeTrialMessage = utils.queryByText(/After a free trial ends/i);
|
||||
|
||||
let emailInput;
|
||||
let nameInput;
|
||||
let submitButton;
|
||||
let chooseButton;
|
||||
let signinButton;
|
||||
let freeTrialMessage;
|
||||
|
||||
try {
|
||||
emailInput = utils.getByLabelText(/email/i);
|
||||
nameInput = utils.getByLabelText(/name/i);
|
||||
submitButton = utils.queryByRole('button', {name: 'Continue'});
|
||||
chooseButton = utils.queryAllByRole('button', {name: 'Choose'});
|
||||
signinButton = utils.queryByRole('button', {name: 'Sign in'});
|
||||
freeTrialMessage = utils.queryByText(/After a free trial ends/i);
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return {
|
||||
nameInput,
|
||||
emailInput,
|
||||
|
@ -89,4 +102,17 @@ describe('SignupPage', () => {
|
|||
|
||||
expect(freeTrialMessage).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('when members are disabled', () => {
|
||||
test('renders an informative message', () => {
|
||||
setup({
|
||||
site: getSiteData({
|
||||
membersSignupAccess: 'none'
|
||||
})
|
||||
});
|
||||
|
||||
const message = getByTestId(document.body, 'members-disabled-notification-text');
|
||||
expect(message).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -238,6 +238,14 @@ export function isInviteOnlySite({site = {}, pageQuery = ''}) {
|
|||
return prices.length === 0 || (site && site.members_signup_access === 'invite');
|
||||
}
|
||||
|
||||
export function isSigninAllowed({site}) {
|
||||
return site?.members_signup_access === 'all' || site?.members_signup_access === 'invite';
|
||||
}
|
||||
|
||||
export function isSignupAllowed({site}) {
|
||||
return site?.members_signup_access === 'all' && (site?.is_stripe_configured || hasOnlyFreePlan({site}));
|
||||
}
|
||||
|
||||
export function hasMultipleProducts({site}) {
|
||||
const products = getAvailableProducts({site});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {getAllProductsForSite, getAvailableProducts, getCurrencySymbol, getFreeProduct, getMemberName, getMemberSubscription, getPriceFromSubscription, getPriceIdFromPageQuery, getSupportAddress, getUrlHistory, hasMultipleProducts, isActiveOffer, isInviteOnlySite, isPaidMember, isSameCurrency, transformApiTiersData} from './helpers';
|
||||
import {getAllProductsForSite, getAvailableProducts, getCurrencySymbol, getFreeProduct, getMemberName, getMemberSubscription, getPriceFromSubscription, getPriceIdFromPageQuery, getSupportAddress, getUrlHistory, hasMultipleProducts, isActiveOffer, isInviteOnlySite, isPaidMember, isSameCurrency, transformApiTiersData, isSigninAllowed, isSignupAllowed} from './helpers';
|
||||
import * as Fixtures from './fixtures-generator';
|
||||
import {site as FixturesSite, member as FixtureMember, offer as FixtureOffer, transformTierFixture as TransformFixtureTiers} from '../utils/test-fixtures';
|
||||
import {isComplimentaryMember} from '../utils/helpers';
|
||||
|
@ -137,8 +137,12 @@ describe('Helpers - ', () => {
|
|||
});
|
||||
|
||||
describe('isInviteOnlySite - ', () => {
|
||||
test('returns true for invite only site', () => {
|
||||
const value = isInviteOnlySite({site: FixturesSite.singleTier.inviteOnly});
|
||||
test('returns true for a site without plans', () => {
|
||||
const value = isInviteOnlySite({site: FixturesSite.singleTier.withoutPlans});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
test('returns true for a site with invite-only members', () => {
|
||||
const value = isInviteOnlySite({site: FixturesSite.singleTier.membersInviteOnly});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
test('returns false for non invite only site', () => {
|
||||
|
@ -147,6 +151,45 @@ describe('Helpers - ', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('isSigninAllowed - ', () => {
|
||||
test('returns true for a site with members enabled', () => {
|
||||
const value = isSigninAllowed({site: FixturesSite.singleTier.basic});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
|
||||
test('returns true for a site with invite-only members', () => {
|
||||
const value = isSigninAllowed({site: FixturesSite.singleTier.membersInviteOnly});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
|
||||
test('returns false for a site with members disabled', () => {
|
||||
const value = isSigninAllowed({site: FixturesSite.singleTier.membersDisabled});
|
||||
expect(value).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSignupAllowed - ', () => {
|
||||
test('returns true for a site with members enabled, and with Stripe configured', () => {
|
||||
const value = isSignupAllowed({site: FixturesSite.singleTier.basic});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
|
||||
test('returns true for a site with members enabled, without Stripe configured, but with only free tiers', () => {
|
||||
const value = isSignupAllowed({site: FixturesSite.singleTier.onlyFreePlanWithoutStripe});
|
||||
expect(value).toBe(true);
|
||||
});
|
||||
|
||||
test('returns false for a site with invite-only members', () => {
|
||||
const value = isSignupAllowed({site: FixturesSite.singleTier.membersInviteOnly});
|
||||
expect(value).toBe(false);
|
||||
});
|
||||
|
||||
test('returns false for a site with members disabled', () => {
|
||||
const value = isSignupAllowed({site: FixturesSite.singleTier.membersDisabled});
|
||||
expect(value).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasMultipleProducts - ', () => {
|
||||
test('returns true for multiple tier site', () => {
|
||||
const value = hasMultipleProducts({site: FixturesSite.multipleTiers.basic});
|
||||
|
|
|
@ -136,7 +136,7 @@ const baseMultiTierSite = getSiteData({
|
|||
export const site = {
|
||||
singleTier: {
|
||||
basic: baseSingleTierSite,
|
||||
inviteOnly: {
|
||||
withoutPlans: {
|
||||
...baseSingleTierSite,
|
||||
portal_plans: []
|
||||
},
|
||||
|
@ -151,6 +151,23 @@ export const site = {
|
|||
withoutName: {
|
||||
...baseSingleTierSite,
|
||||
portal_name: false
|
||||
},
|
||||
withoutStripe: {
|
||||
...baseSingleTierSite,
|
||||
is_stripe_configured: false
|
||||
},
|
||||
onlyFreePlanWithoutStripe: {
|
||||
...baseSingleTierSite,
|
||||
portal_plans: ['free'],
|
||||
is_stripe_configured: false
|
||||
},
|
||||
membersInviteOnly: {
|
||||
...baseSingleTierSite,
|
||||
members_signup_access: 'invite'
|
||||
},
|
||||
membersDisabled: {
|
||||
...baseSingleTierSite,
|
||||
members_signup_access: 'none'
|
||||
}
|
||||
},
|
||||
multipleTiers: {
|
||||
|
|
|
@ -45,9 +45,11 @@ function finaliseStructuredData(meta) {
|
|||
}
|
||||
|
||||
function getMembersHelper(data, frontendKey) {
|
||||
if (!settingsCache.get('members_enabled')) {
|
||||
// Do not load Portal if both Memberships and Tips & Donations are disabled
|
||||
if (!settingsCache.get('members_enabled') && !settingsCache.get('donations_enabled')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const {scriptUrl} = getFrontendAppConfig('portal');
|
||||
|
||||
const colorString = (_.has(data, 'site._preview') && data.site.accent_color) ? data.site.accent_color : '';
|
||||
|
|
Loading…
Add table
Reference in a new issue