Skip to content

Instantly share code, notes, and snippets.

@aziaziazi
Last active February 28, 2020 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aziaziazi/952f058f48cd1d412ffa848b3b78f2a4 to your computer and use it in GitHub Desktop.
Save aziaziazi/952f058f48cd1d412ffa848b3b78f2a4 to your computer and use it in GitHub Desktop.
memberstack
// An article-page template
const ArticlePage = ({privateArticle}) => {
// get member, paywall state and private page updater from context
const {
member,
paywall: { paywallIsOpen, updateInPrivatePage }
} = useContext(AuthContext);
// update private page status at mount and unmount
useEffect(() => {
if (privateArticle) updateInPrivatePage(true)
return () => {
updateInPrivatePage(false)
}
}, [member])
// only show content (or part of it) if user has access
return paywallIsOpen ? null : <div>private page content</div>
}
// place this file on the top of the dom so it won't be updated
const AuthContext = React.createContext(null);
const AuthProvider = ({ children }) => {
// load MS script and
// - update members with MS data
// - toggle loaded to true
const [member, loaded] = useMemberStack()
// create state for
// - inPrivatePage: user is currently in a private page
// - setInPrivatePage: toggle inPrivatePage (used at componentDidMount in pages)
const [inPrivatePage, setInPrivatePage] = useState(false)
// just a handler because state updater won't work directly
const updateInPrivatePage = isOpen => setInPrivatePage(isOpen)
// paywall should be open if a visitor not loggedIn visit a private page
const paywallIsOpen = inPrivatePage && member && !member.loggedIn
const contextValue = {
member,
loaded,
paywall: {paywallIsOpen, updateInPrivatePage}
};
// place in the context all states and private page updater
// show/hide paywall with styled-components. It needs to be here
// because it contains auth buttons that can't be re-rendered
return <AuthContext.Provider value={contextValue}>
<NavBar/>
<AuthPaywall isOpen={paywallIsOpen}/>
{loaded && children}
</AuthContext.Provider>
}
import { useState,useEffect } from "react";
import { frenchTranslations } from './memberStackTransaltions';
let cached = null;
export const useMemberStack = () => {
const [memberStack, setMemberStack] = useState({
member: null,
loaded: false
});
useEffect(
() => {
// If cache exist that means another instance of this hook
// already loaded this script, so no need to load again.
if (cached !== null) {
setMemberStack({
member: cached,
loaded: true,
});
} else {
// set translations before script loading
window.textOverride = frenchTranslations;
let script = document.createElement('script');
script.src = 'https://api.memberstack.io/static/memberstack.js?custom';
script.setAttribute('data-memberstack-id', '70b4aafcd75ae5b807415153053fd9b1');
script.async = true;
const onScriptLoad = () => {
window.MemberStack.onReady.then(member => {
cached = member;
setMemberStack({
member,
loaded: true
});
})
};
script.addEventListener('load', onScriptLoad);
document.body.appendChild(script);
return () => {
script.removeEventListener('load', onScriptLoad);
};
}
},
[]
);
return [memberStack.member, memberStack.loaded];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment