From 926df30ccd18cc2c3b8b48dc075c55e1140b0fd1 Mon Sep 17 00:00:00 2001 From: Rishabh Date: Wed, 27 Apr 2022 20:38:06 +0530 Subject: [PATCH] Refined newsletter management for logged-in members refs https://github.com/TryGhost/Team/issues/1559 - extracts newsletter management in a common component for use across pages --- .../components/common/NewsletterManagement.js | 140 ++++++++++++++++++ .../src/components/pages/AccountEmailPage.js | 137 +++-------------- 2 files changed, 160 insertions(+), 117 deletions(-) create mode 100644 ghost/portal/src/components/common/NewsletterManagement.js diff --git a/ghost/portal/src/components/common/NewsletterManagement.js b/ghost/portal/src/components/common/NewsletterManagement.js new file mode 100644 index 0000000000..ad23d739e8 --- /dev/null +++ b/ghost/portal/src/components/common/NewsletterManagement.js @@ -0,0 +1,140 @@ +import AppContext from '../../AppContext'; +import CloseButton from '../common/CloseButton'; +import BackButton from '../common/BackButton'; +import {useContext, useState} 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 ( +
+
+ ); +} + +function NewsletterPrefSection({newsletter, subscribedNewsletters, setSubscribedNewsletters}) { + const isChecked = subscribedNewsletters.some((d) => { + return d.id === newsletter?.id; + }); + const [description, setDescription] = useState(newsletter?.description || ''); + const [timeoutId, setTimeoutId] = useState(null); + let finalDescription = description; + if (!description) { + finalDescription = isChecked ? 'Subscribed' : 'Unsubscribed'; + } + return ( +
+
+

{newsletter.name}

+

{finalDescription}

+
+
+ { + let updatedNewsletters = []; + if (!checked) { + updatedNewsletters = subscribedNewsletters.filter((d) => { + return d.id !== newsletter.id; + }); + setDescription('Unsubscribed'); + clearTimeout(timeoutId); + let newTimeoutId = setTimeout(() => { + setDescription(newsletter?.description); + }, 3000); + setTimeoutId(newTimeoutId); + } else { + updatedNewsletters = subscribedNewsletters.filter((d) => { + return d.id !== newsletter.id; + }).concat(newsletter); + setDescription('Subscribed'); + clearTimeout(timeoutId); + let newTimeoutId = setTimeout(() => { + setDescription(newsletter?.description); + }, 3000); + setTimeoutId(newTimeoutId); + } + setSubscribedNewsletters(updatedNewsletters); + }} checked={isChecked} /> +
+
+ ); +} + +function NewsletterPrefs({subscribedNewsletters, setSubscribedNewsletters}) { + const {site} = useContext(AppContext); + const newsletters = getSiteNewsletters({site}); + return newsletters.map((newsletter) => { + return ( + + ); + }); +} + +function ShowPaidMemberMessage({site, isPaid}) { + if (isPaid) { + return ( +

Unsubscribing from emails will not cancel your paid subscription to {site?.title}

+ ); + } + return null; +} + +export default function NewsletterManagement({ + subscribedNewsletters, + updateSubscribedNewsletters, + unsubscribeAll, + isPaidMember +}) { + const isDisabled = !subscribedNewsletters?.length; + const {brandColor, site} = useContext(AppContext); + return ( +
+ + +
+
+ { + let newsletters = updatedNewsletters.map((d) => { + return { + id: d.id + }; + }); + updateSubscribedNewsletters(newsletters); + }} + /> +
+
+
+
+ { + unsubscribeAll(); + }} + disabled={isDisabled} + brandColor={brandColor} + isPrimary={false} + label='Unsubscribe from all' + isDestructive={true} + style={{width: '100%'}} + /> + +
+
+
+ ); +} diff --git a/ghost/portal/src/components/pages/AccountEmailPage.js b/ghost/portal/src/components/pages/AccountEmailPage.js index cc97f18480..add4be5bd5 100644 --- a/ghost/portal/src/components/pages/AccountEmailPage.js +++ b/ghost/portal/src/components/pages/AccountEmailPage.js @@ -1,131 +1,34 @@ import AppContext from '../../AppContext'; -import CloseButton from '../common/CloseButton'; -import BackButton from '../common/BackButton'; import {useContext, useEffect, useState} from 'react'; -import Switch from '../common/Switch'; -import {getSiteNewsletters} from '../../utils/helpers'; -import ActionButton from '../common/ActionButton'; +import {isPaidMember} from '../../utils/helpers'; +import NewsletterManagement from '../common/NewsletterManagement'; const React = require('react'); -function AccountHeader() { - const {brandColor, lastPage, onAction} = useContext(AppContext); - return ( -
-
- ); -} - -function NewsletterPrefSection({newsletter, subscribedNewsletters, setSubscribedNewsletters}) { - const isChecked = subscribedNewsletters.some((d) => { - return d.id === newsletter?.id; - }); - return ( -
-
-

{newsletter.name}

-

{newsletter.description}

-
-
- { - let updatedNewsletters = []; - if (!checked) { - updatedNewsletters = subscribedNewsletters.filter((d) => { - return d.id !== newsletter.id; - }); - } else { - updatedNewsletters = subscribedNewsletters.filter((d) => { - return d.id !== newsletter.id; - }).concat(newsletter); - } - setSubscribedNewsletters(updatedNewsletters); - }} checked={isChecked} /> -
-
- ); -} - -function NewsletterPrefs({subscribedNewsletters, setSubscribedNewsletters}) { - const {site} = useContext(AppContext); - const newsletters = getSiteNewsletters({site}); - return newsletters.map((newsletter) => { - return ( - - ); - }); -} - export default function AccountEmailPage() { - const {brandColor, member, onAction} = useContext(AppContext); + const {member, onAction} = useContext(AppContext); const defaultSubscribedNewsletters = [...(member.newsletters || [])]; const [subscribedNewsletters, setSubscribedNewsletters] = useState(defaultSubscribedNewsletters); useEffect(() => { - setSubscribedNewsletters(member.newsletters); + setSubscribedNewsletters(member?.newsletters || []); }, [member.newsletters]); return ( -
- - -
-
- -
-
-
-
-
- { - let newsletters = subscribedNewsletters.map((d) => { - return { - id: d.id - }; - }); - onAction('showPopupNotification', { - action: 'updated:success', - message: `Newsletter preference updated.` - }); - onAction('updateNewsletterPreference', {newsletters}); - }} - disabled={false} - brandColor={brandColor} - label='Update' - style={{width: '100%'}} - /> -
- { - onAction('showPopupNotification', { - action: 'updated:success', - message: `Newsletter preference updated.` - }); - onAction('updateNewsletterPreference', {newsletters: []}); - }} - disabled={false} - brandColor={brandColor} - isPrimary={false} - label='Unsubscribe from all' - isDestructive={true} - style={{width: '100%'}} - /> -

Unsubscribing from emails will not cancel your paid subscription to The Chinese Cinema

-
-
-
+ { + setSubscribedNewsletters(updatedNewsletters); + onAction('updateNewsletterPreference', {newsletters: updatedNewsletters}); + }} + unsubscribeAll={() => { + setSubscribedNewsletters([]); + onAction('showPopupNotification', { + action: 'updated:success', + message: `Newsletter preference updated.` + }); + onAction('updateNewsletterPreference', {newsletters: []}); + }} + isPaidMember={isPaidMember({member})} + /> ); }