0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

🐛 Fixed UI glitch on unsubscribe page in Portal

refs https://ghost.slack.com/archives/C02G9E68C/p1699391515110759

When the unsubscribe page first showed, member is set to `undefined`. This cause the normal NewsletterManagement page to be visible, but with the wrong settings. This caused the switches to quickly change between on/off state, making it look like some setting was changed when it was not.

To fix this, I added a loading page to the unsubscribe page.

Apart from this, the current error page now will get shown correctly when the uuid in the url is invalid. And the toast message on the top will be hidden if the newsletter uuid in the url is missing or invalid.
This commit is contained in:
Simon Backx 2023-11-08 12:59:31 +01:00 committed by Simon Backx
parent 986296cac9
commit 395c109c67

View file

@ -8,6 +8,7 @@ import CloseButton from '../common/CloseButton';
import {ReactComponent as WarningIcon} from '../../images/icons/warning-fill.svg';
import Interpolate from '@doist/react-interpolate';
import {SYNTAX_I18NEXT} from '@doist/react-interpolate';
import LoadingPage from './LoadingPage';
function SiteLogo() {
const {site} = useContext(AppContext);
@ -44,6 +45,7 @@ export default function UnsubscribePage() {
const {site, pageData, onAction, t} = useContext(AppContext);
const api = setupGhostApi({siteUrl: site.url});
const [member, setMember] = useState();
const [loading, setLoading] = useState(true);
const siteNewsletters = getSiteNewsletters({site});
const defaultNewsletters = siteNewsletters.filter((d) => {
return d.subscribe_on_signup;
@ -57,12 +59,26 @@ export default function UnsubscribePage() {
useEffect(() => {
const ghostApi = setupGhostApi({siteUrl: site.url});
(async () => {
const memberData = await ghostApi.member.newsletters({uuid: pageData.uuid});
let memberData;
try {
memberData = await ghostApi.member.newsletters({uuid: pageData.uuid});
setMember(memberData ?? null);
setLoading(false);
} catch (e) {
// eslint-disable-next-line no-console
console.error('[PORTAL] Error fetching member newsletters', e);
setMember(null);
setLoading(false);
return;
}
if (memberData === null) {
return;
}
setMember(memberData);
const memberNewsletters = memberData?.newsletters || [];
setSubscribedNewsletters(memberNewsletters);
if (siteNewsletters?.length === 1 && !commentsEnabled) {
if (siteNewsletters?.length === 1 && !commentsEnabled && !pageData.newsletterUuid) {
// Unsubscribe from all the newsletters, because we only have one
const updatedData = await updateMemberNewsletters({
api: ghostApi,
@ -93,8 +109,15 @@ export default function UnsubscribePage() {
})();
}, [commentsEnabled, pageData.uuid, pageData.newsletterUuid, pageData.comments, site.url, siteNewsletters?.length]);
// Case: Email not found
if (member === null) {
if (loading) {
// Loading member data from the API based on the uuid
return (
<LoadingPage />
);
}
// Case: invalid uuid passed
if (!member) {
return (
<div className='gh-portal-content gh-portal-feedback with-footer'>
<CloseButton />
@ -176,6 +199,11 @@ export default function UnsubscribePage() {
const unsubscribedNewsletter = siteNewsletters?.find((d) => {
return d.uuid === pageData.newsletterUuid;
});
if (!unsubscribedNewsletter) {
return null;
}
const hideClassName = hasInteracted ? 'gh-portal-hide' : '';
return (
<>