diff --git a/ghost/portal/src/components/Frame.styles.js b/ghost/portal/src/components/Frame.styles.js index 06a96b0868..a1cfb41969 100644 --- a/ghost/portal/src/components/Frame.styles.js +++ b/ghost/portal/src/components/Frame.styles.js @@ -20,6 +20,7 @@ import {OfferPageStyles} from './pages/OfferPage'; import {FeedbackPageStyles} from './pages/FeedbackPage'; import EmailSuppressedPage from '!!raw-loader!./pages/EmailSuppressedPage.css'; import EmailSuppressionFAQ from '!!raw-loader!./pages/EmailSuppressionFAQ.css'; +import EmailReceivingFAQ from '!!raw-loader!./pages/EmailReceivingFAQ.css'; // Global styles const FrameStyles = ` @@ -322,6 +323,12 @@ const FrameStyles = ` z-index: 9999; } +.gh-portal-popup-container.large-size { + width: 720px; + justify-content: flex-start; + padding: 0; +} + .gh-portal-popup-container.full-size { width: 100vw; min-height: 100vh; @@ -499,6 +506,12 @@ const FrameStyles = ` margin-bottom: 20px; } +.gh-portal-section.flex { + display: flex; + flex-direction: column; + gap: 2rem; +} + .gh-portal-detail-header { position: relative; display: flex; @@ -515,6 +528,8 @@ const FrameStyles = ` display: flex; align-items: center; justify-content: space-between; + flex-direction: column; + gap: 2rem; } .gh-portal-list-header { @@ -771,10 +786,14 @@ const FrameStyles = ` const MobileStyles = ` @media (max-width: 1440px) { - .gh-portal-popup-container:not(.full-size):not(.preview) { + .gh-portal-popup-container:not(.full-size):not(.large-size):not(.preview) { width: 460px; } + .gh-portal-popup-container.large-size { + width: 600px; + } + .gh-portal-input { height: 42px; margin-bottom: 16px; @@ -857,6 +876,10 @@ const MobileStyles = ` justify-content: flex-start; } + .gh-portal-popup-container.large-size { + padding: 0 !important; + } + .gh-portal-popup-wrapper.account-home, .gh-portal-popup-container.account-home { background: var(--grey13); @@ -1177,6 +1200,7 @@ export function getFrameStyles({site}) { MultipleProductsGlobalStyles + FeedbackPageStyles + EmailSuppressedPage + - EmailSuppressionFAQ; + EmailSuppressionFAQ + + EmailReceivingFAQ; return FrameStyle; } diff --git a/ghost/portal/src/components/Global.styles.js b/ghost/portal/src/components/Global.styles.js index 69eff9c5c2..3f84b3580f 100644 --- a/ghost/portal/src/components/Global.styles.js +++ b/ghost/portal/src/components/Global.styles.js @@ -20,6 +20,7 @@ export const GlobalStyles = ` --grey14: #fbfbfb; --white: #fff; --red: #f02525; + --darkerRed: #C50202; --yellow: #FFDC15; --green: #7FC724; } @@ -77,6 +78,18 @@ export const GlobalStyles = ` letter-spacing: -0.019em; } + h4 { + font-size: 19px; + font-weight: 700; + letter-spacing: -0.02em; + } + + h5 { + font-size: 15px; + font-weight: 700; + letter-spacing: -0.02em; + } + p { font-size: 15px; line-height: 1.5em; @@ -107,6 +120,31 @@ export const GlobalStyles = ` line-height: 1.5em; } + .gh-longform { + padding: 6vmin 10vmin 4vmin 6vmin; + } + + .gh-longform h3 { + margin-top: 0; + margin-bottom: 1em; + } + + .gh-longform h4 { + margin-top: 2.5em; + margin-bottom: 1.25em; + } + + .gh-longform h5 { + margin-top: 0; + margin-bottom: 0.5em; + } + + .gh-longform .gh-portal-btn { + width: calc(100% + 4vmin); + margin-top: 4rem; + margin-right: -4vmin; + } + @media (max-width: 1440px) { h1 { font-size: 32px; @@ -139,6 +177,14 @@ export const GlobalStyles = ` font-size: 24px; letter-spacing: -0.019em; } + + .gh-longform { + padding: 10vmin 12vmin 10vmin 10vmin; + } + + .gh-mobile-shortener { + display: none; + } } `; diff --git a/ghost/portal/src/components/PopupModal.js b/ghost/portal/src/components/PopupModal.js index abc67fc262..66d29b65f4 100644 --- a/ghost/portal/src/components/PopupModal.js +++ b/ghost/portal/src/components/PopupModal.js @@ -185,6 +185,10 @@ class PopupContent extends React.Component { } } + if (page === 'emailSuppressionFAQ' || page === 'emailReceivingFAQ') { + pageClass += ' large-size'; + } + let className = 'gh-portal-popup-container'; if (hasMode(['preview'])) { diff --git a/ghost/portal/src/components/common/ActionButton.js b/ghost/portal/src/components/common/ActionButton.js index 745c7d7591..6b29098f9c 100644 --- a/ghost/portal/src/components/common/ActionButton.js +++ b/ghost/portal/src/components/common/ActionButton.js @@ -29,6 +29,16 @@ export const ActionButtonStyles = ` border-color: var(--red); } + .gh-feature-suppressions .gh-portal-btn-destructive:not(:disabled) { + color: var(--red); + border-color: var(--red); + } + + .gh-feature-suppressions .gh-portal-btn-destructive:not(:disabled):hover { + color: var(--darkerRed); + border-color: var(--darkerRed); + } + .gh-portal-btn-text { padding: 0; font-weight: 500; diff --git a/ghost/portal/src/components/common/NewsletterManagement.js b/ghost/portal/src/components/common/NewsletterManagement.js index 199296b302..3a0bb20bb2 100644 --- a/ghost/portal/src/components/common/NewsletterManagement.js +++ b/ghost/portal/src/components/common/NewsletterManagement.js @@ -3,7 +3,7 @@ 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 {getSiteNewsletters, hasMemberGotEmailSuppression} from '../../utils/helpers'; import ActionButton from '../common/ActionButton'; import {ReactComponent as CheckmarkIcon} from '../../images/icons/check-circle.svg'; @@ -151,7 +151,7 @@ export default function NewsletterManagement({ isCommentsEnabled, enableCommentNotifications }) { - const {brandColor, site} = useContext(AppContext); + const {brandColor, onAction, member, site} = useContext(AppContext); const isDisabled = !subscribedNewsletters?.length && ((isCommentsEnabled && !enableCommentNotifications) || !isCommentsEnabled); const EmptyNotification = () => { return null; @@ -162,7 +162,7 @@ export default function NewsletterManagement({ -
+
-
+
+ {hasMemberGotEmailSuppression({member}) && !isDisabled && + }
); diff --git a/ghost/portal/src/components/pages/AccountHomePage/AccountHomePage.css b/ghost/portal/src/components/pages/AccountHomePage/AccountHomePage.css index e7fffa527c..d91267a396 100644 --- a/ghost/portal/src/components/pages/AccountHomePage/AccountHomePage.css +++ b/ghost/portal/src/components/pages/AccountHomePage/AccountHomePage.css @@ -73,6 +73,7 @@ footer.gh-portal-account-footer { color: var(--red); font-weight: 500; font-size: 1.25rem; + letter-spacing: 0.2px; } .gh-portal-email-notice-icon { diff --git a/ghost/portal/src/components/pages/AccountHomePage/components/EmailPreferencesAction.js b/ghost/portal/src/components/pages/AccountHomePage/components/EmailPreferencesAction.js index 212f020d57..26386549ae 100644 --- a/ghost/portal/src/components/pages/AccountHomePage/components/EmailPreferencesAction.js +++ b/ghost/portal/src/components/pages/AccountHomePage/components/EmailPreferencesAction.js @@ -17,7 +17,7 @@ function EmailPreferencesAction() { ? (

- You're currently not receiving emails + You're currently not receiving emails

) :

Update your preferences

diff --git a/ghost/portal/src/components/pages/EmailReceivingFAQ.css b/ghost/portal/src/components/pages/EmailReceivingFAQ.css new file mode 100644 index 0000000000..4d5b830d17 --- /dev/null +++ b/ghost/portal/src/components/pages/EmailReceivingFAQ.css @@ -0,0 +1,3 @@ +.gh-email-receiving-faq { + +} diff --git a/ghost/portal/src/components/pages/EmailReceivingFAQ.js b/ghost/portal/src/components/pages/EmailReceivingFAQ.js new file mode 100644 index 0000000000..031f7c788d --- /dev/null +++ b/ghost/portal/src/components/pages/EmailReceivingFAQ.js @@ -0,0 +1,43 @@ +import AppContext from 'AppContext'; +import {useContext} from 'react'; +import BackButton from 'components/common/BackButton'; +import CloseButton from 'components/common/CloseButton'; +import {getSupportAddress} from 'utils/helpers'; + +export default function EmailReceivingPage() { + const {brandColor, onAction, site} = useContext(AppContext); + + const supportAddress = `mailto:${getSupportAddress({site})}`; + + return ( +
+
+ { + onAction('switchPage', {page: 'accountEmail', lastPage: 'accountHome'}); + }} /> + +
+ +
+

Help! I'm not receiving subscription emails

+

If you're not receiving the newsletter, the first course of action is to check your account settings to ensure your email address is correct and your email preferences are set to subscribed.

+

Check the email on your account

+

If you need to correct a typo in your email address or change the email address associated with your membership, click Edit next to your address when viewing your account settings.

+

Once saved, you'll need to confirm the change by clicking the confirmation link, which will arrive via email to your new email address's inbox.

+

Check spam & promotional folders

+

Once the email has been confirmed, the next course of action is to check your spam folder, and any promotional folders, set up by your mail provider.

+
Spam
+

If the newsletter landed in spam, you can mark the email as 'not spam' within your mail client — this should ensure that future newsletters arrive in your inbox going forward.

+
Promotional folder
+

If the newsletter arrived in your promotional folder, move the email to your main inbox. This should teach your mail client to place the newsletter in your primary inbox going forward.

+
Add to Contacts
+

To help avoid future emails arriving in spam or promotional folders, you can also add the newsletter 'From' email address to your contact list.

+

Check with your mail provider

+

For those with corporate-based email addresses, you may need to reach out to your help desk or IT department to troubleshoot any potential reasons that may prevent you from receiving email newsletters.

+

{ + supportAddress && window.open(supportAddress); + }}>Need more help? Contact support

+
+
+ ); +} diff --git a/ghost/portal/src/components/pages/EmailSuppressedPage.css b/ghost/portal/src/components/pages/EmailSuppressedPage.css index 1a813ab495..707b9bd849 100644 --- a/ghost/portal/src/components/pages/EmailSuppressedPage.css +++ b/ghost/portal/src/components/pages/EmailSuppressedPage.css @@ -15,10 +15,15 @@ color: var(--grey6); } -.gh-email-suppressed-page-button { - color: var(--grey3); +.gh-email-faq-page-button { + color: var(--grey6); cursor: pointer; font-size: 1.5rem; text-decoration: underline; background: none; + transition: color linear 100ms; +} + +.gh-email-faq-page-button:hover { + color: var(--grey5); } diff --git a/ghost/portal/src/components/pages/EmailSuppressedPage.js b/ghost/portal/src/components/pages/EmailSuppressedPage.js index e48de3634e..9b854e9f76 100644 --- a/ghost/portal/src/components/pages/EmailSuppressedPage.js +++ b/ghost/portal/src/components/pages/EmailSuppressedPage.js @@ -44,8 +44,8 @@ export default function EmailSuppressedPage() {

diff --git a/ghost/portal/src/components/pages/EmailSuppressionFAQ.js b/ghost/portal/src/components/pages/EmailSuppressionFAQ.js index 1ba8810a1f..1f5773377a 100644 --- a/ghost/portal/src/components/pages/EmailSuppressionFAQ.js +++ b/ghost/portal/src/components/pages/EmailSuppressionFAQ.js @@ -1,22 +1,37 @@ import AppContext from 'AppContext'; import {useContext} from 'react'; +import BackButton from 'components/common/BackButton'; import CloseButton from 'components/common/CloseButton'; +import {getSupportAddress} from 'utils/helpers'; export default function EmailSuppressedPage() { - const {onAction} = useContext(AppContext); + const {brandColor, onAction, site} = useContext(AppContext); - const onClose = () => { - onAction('switchPage', {page: 'emailSuppressed', lastPage: 'accountHome'}); - }; + const supportAddress = `mailto:${getSupportAddress({site})}`; return (
- + { + onAction('switchPage', {page: 'emailSuppressed', lastPage: 'accountHome'}); + }} /> +
-
-

Why is my email disabled?

+
+

Why has my email been disabled?

+

Newsletters can be disabled on your account for two reasons: A previous email was marked as spam, or attempting to send an email resulted in a permanent failure (bounce).

+

Spam complaints

+

If a newsletter is flagged as spam, emails are automatically disabled for that address to make sure you no longer receive any unwanted messages.

+

If the spam complaint was accidental, or you would like to begin receiving emails again, you can resubscribe to emails by clicking the button on the previous screen.

+

Once resubscribed, if you still don't see emails in your inbox, check your spam folder. Some inbox providers keep a record of previous spam complaints and will continue to flag emails. If this happens, mark the latest newsletter as 'Not spam' to move it back to your primary inbox.

+

Permanent failure (bounce)

+

When an inbox fails to accept an email it is commonly called a bounce. In many cases, this can be temporary. However, in some cases, a bounced email can be returned as a permanent failure when an email address is invalid or non-existent.

+

In the event a permanent failure is received when attempting to send a newsletter, emails will be disabled on the account.

+

If you would like to start receiving emails again, the best next steps are to check your email address on file for any issues and then click resubscribe on the previous screen.

+

{ + supportAddress && window.open(supportAddress); + }}>Need more help? Contact support

); diff --git a/ghost/portal/src/pages.js b/ghost/portal/src/pages.js index 90b689794d..7c6a134020 100644 --- a/ghost/portal/src/pages.js +++ b/ghost/portal/src/pages.js @@ -12,6 +12,7 @@ import UnsubscribePage from './components/pages/UnsubscribePage'; import FeedbackPage from './components/pages/FeedbackPage'; import EmailSuppressedPage from './components/pages/EmailSuppressedPage'; import EmailSuppressionFAQ from './components/pages/EmailSuppressionFAQ'; +import EmailReceivingFAQ from './components/pages/EmailReceivingFAQ'; /** List of all available pages in Portal, mapped to their UI component * Any new page added to portal needs to be mapped here @@ -30,7 +31,8 @@ const Pages = { offer: OfferPage, feedback: FeedbackPage, emailSuppressed: EmailSuppressedPage, - emailSuppressionFAQ: EmailSuppressionFAQ + emailSuppressionFAQ: EmailSuppressionFAQ, + emailReceivingFAQ: EmailReceivingFAQ }; /** Return page if valid, fallback to signup */ diff --git a/ghost/portal/src/utils/helpers.js b/ghost/portal/src/utils/helpers.js index e8d5abfdfd..5b025ecd92 100644 --- a/ghost/portal/src/utils/helpers.js +++ b/ghost/portal/src/utils/helpers.js @@ -657,6 +657,13 @@ export const getMemberEmail = ({member}) => { return member.email; }; +export const hasMemberGotEmailSuppression = ({member}) => { + if (!member) { + return ''; + } + return member.email_suppression; +}; + export const getFirstpromoterId = ({site}) => { return (site && site.firstpromoter_account); };