0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-25 02:31:59 -05:00

Added dummy newsletter preferences section for member account

refs https://github.com/TryGhost/Team/issues/1440

- adds static email preferences section in account home page
- adds new account email page for preferences
- adds new fixture for multiple newsletters
- adds basic helper for multiple newsletters
This commit is contained in:
Rishabh 2022-03-23 17:11:43 +05:30
parent 2c81e94f74
commit f03ef9538d
6 changed files with 140 additions and 5 deletions

View file

@ -0,0 +1,87 @@
import AppContext from '../../AppContext';
import CloseButton from '../common/CloseButton';
import BackButton from '../common/BackButton';
import {useContext} from 'react';
import Switch from '../common/Switch';
import {getSiteNewsletters} from '../../utils/helpers';
import ActionButton from '../common/ActionButton';
const React = require('react');
function AccountHeader() {
const {brandColor, lastPage, onAction} = useContext(AppContext);
return (
<header className='gh-portal-detail-header'>
<BackButton brandColor={brandColor} hidden={!lastPage} onClick={(e) => {
onAction('back');
}} />
<h3 className='gh-portal-main-title'>Email preferences</h3>
</header>
);
}
function NewsletterPrefSection({newsletter}) {
return (
<section>
<div className='gh-portal-list-detail'>
<h3>{newsletter.name}</h3>
</div>
<div>
<Switch id={newsletter.id} onToggle={(e) => {
// handle newsletter pref toggle
}} checked={false} />
</div>
</section>
);
}
function NewsletterPrefs() {
const {site} = useContext(AppContext);
const newsletters = getSiteNewsletters({site});
return newsletters.map((newsletter) => {
return (
<>
<NewsletterPrefSection key={newsletter?.id} newsletter={newsletter} />
</>
);
});
}
export default function AccountEmailPage() {
const {brandColor} = useContext(AppContext);
return (
<div className='gh-portal-content with-footer'>
<CloseButton />
<AccountHeader />
<div className='gh-portal-section'>
<div className='gh-portal-list'>
<NewsletterPrefs />
</div>
</div>
<footer className='gh-portal-action-footer'>
<div style={{width: '100%'}}>
<div style={{marginBottom: '12px'}}>
<ActionButton
isRunning={false}
onClick={(e) => {}}
disabled={false}
brandColor={brandColor}
label='Update'
style={{width: '100%'}}
/>
</div>
<ActionButton
isRunning={false}
onClick={(e) => {}}
disabled={false}
brandColor={brandColor}
isPrimary={false}
label='Unsubscribe from all'
isDestructive={true}
style={{width: '100%'}}
/>
</div>
</footer>
</div>
);
}

View file

@ -3,7 +3,7 @@ import MemberAvatar from '../common/MemberGravatar';
import ActionButton from '../common/ActionButton';
import CloseButton from '../common/CloseButton';
import Switch from '../common/Switch';
import {getMemberSubscription, getMemberTierName, getUpdatedOfferPrice, hasMultipleProductsFeature, hasOnlyFreePlan, isComplimentaryMember} from '../../utils/helpers';
import {getMemberSubscription, getMemberTierName, getUpdatedOfferPrice, hasMultipleNewsletters, hasMultipleProductsFeature, hasOnlyFreePlan, isComplimentaryMember} from '../../utils/helpers';
import {getDateString} from '../../utils/date-time';
import {ReactComponent as LoaderIcon} from '../../images/icons/loader.svg';
import {ReactComponent as OfferTagIcon} from '../../images/icons/offer-tag.svg';
@ -324,7 +324,7 @@ const AccountActions = () => {
</section>
<PaidAccountActions />
<EmailPreferencesAction />
<section>
<div className='gh-portal-list-detail'>
<h3>Email newsletter</h3>
@ -342,6 +342,26 @@ const AccountActions = () => {
);
};
function EmailPreferencesAction() {
const {site, onAction} = useContext(AppContext);
if (!hasMultipleNewsletters({site})) {
return null;
}
return (
<section>
<div className='gh-portal-list-detail'>
<h3>Email Preference</h3>
</div>
<button className='gh-portal-btn gh-portal-btn-list' onClick={(e) => {
onAction('switchPage', {
page: 'accountEmail',
lastPage: 'accountHome'
});
}}>Manage</button>
</section>
);
}
const SubscribeButton = () => {
const {site, action, brandColor, onAction} = useContext(AppContext);
const {is_stripe_configured: isStripeConfigured} = site;

View file

@ -5,6 +5,7 @@ import MagicLinkPage from './components/pages/MagicLinkPage';
import LoadingPage from './components/pages/LoadingPage';
import AccountPlanPage from './components/pages/AccountPlanPage';
import AccountProfilePage from './components/pages/AccountProfilePage';
import AccountEmailPage from './components/pages/AccountEmailPage';
import OfferPage from './components/pages/OfferPage';
/** List of all available pages in Portal, mapped to their UI component
@ -16,6 +17,7 @@ const Pages = {
accountHome: AccountHomePage,
accountPlan: AccountPlanPage,
accountProfile: AccountProfilePage,
accountEmail: AccountEmailPage,
magiclink: MagicLinkPage,
loading: LoadingPage,
offer: OfferPage

View file

@ -36,7 +36,8 @@ export function getSiteData({
portalButtonIcon: portal_button_icon = 'icon-1',
portalButtonSignupText: portal_button_signup_text = 'Subscribe now',
portalButtonStyle: portal_button_style = 'icon-and-text',
membersSupportAddress: members_support_address = 'support@example.com'
membersSupportAddress: members_support_address = 'support@example.com',
newsletters = []
} = {}) {
return {
title,
@ -59,7 +60,8 @@ export function getSiteData({
portal_button_icon,
portal_button_signup_text,
portal_button_style,
members_support_address
members_support_address,
newsletters
};
}

View file

@ -104,7 +104,17 @@ export const site = getSiteData({
portalButtonIcon: 'icon-1',
portalButtonSignupText: 'Subscribe now',
portalButtonStyle: 'icon-and-text',
membersSupportAddress: 'support@example.com'
membersSupportAddress: 'support@example.com',
newsletters: [
{
id: 'weekly',
name: 'Weekly Rundown'
},
{
id: 'daily',
name: 'Daily Brief'
}
]
});
export const offer = getOfferData({

View file

@ -373,6 +373,20 @@ export function hasFreeProductPrice({site}) {
return allowSelfSignup && portalPlans.includes('free');
}
export function getSiteNewsletters({site}) {
const {
newsletters
} = site || {};
return newsletters;
}
export function hasMultipleNewsletters({site}) {
const {
newsletters
} = site || {};
return newsletters?.length > 1;
}
export function hasOnlyFreeProduct({site}) {
const products = getSiteProducts({site});
return (products.length === 1 && hasFreeProductPrice({site}));