Before we start implementing the pages and sections, let's create a component that will act as a guard to protect the pages that require authentication, like the /account and the /account/orders page.
The AuthGuard component will redirect your customer to a given URL if they try to access a password-protected page. Also, the AuthGuard component will redirect your customers to their /account page if they are already logged in and try to access the register and/or login page.
The AuthGuard component takes 3 props:
prop name | type | description |
|
| The status in which the customer is authorized to access the children's component. |
|
| The url that the customer should be redirected to. |
|
| The component that will be wrapped and protected by |
To create the AuthGuard Component:
On your local environment, create a new folder inside
src/componentsand name it asAuthGuard.Create an
index.jsfile inside theAuthGuardfolder.Create a
styles.module.cssfile inside theAuthGuardfolder.
You can also create Sections and Components via Shogun Frontend IDE:
Click on the Sections icon from the sidebar.
Open any
Section.Click on
Componentson the left side of the screen.Click on the + (plus sign) button to create a new
Component.The
IDEwill refresh with sample code.Name the
ComponentasAuthGuardby clicking on the pencil icon button in the top left corner of your screen. When you are done, click the checkmark icon to save the name.Click
SAVEto save theComponent.
import React from 'react'
import { useCustomerState } from 'frontend-customer'
import { useRouter } from 'frontend-router'
const REDIRECT_DELAY = 750
const AuthGuard = ({ allowedAuthStatus, redirectUrl, children }) => {
/*
* status: Status of loading customer's data
* isLoggedIn: Whether the customer is logged in or not
*/
const { status, isLoggedIn } = useCustomerState()
const router = useRouter()
const [firstLoad, setFirstLoad] = React.useState(false)
const authStatus = React.useMemo(() => {
if (status === 'initial' || status === 'loading') {
return status
}
return isLoggedIn ? 'authenticated' : 'unauthenticated'
}, [status, isLoggedIn])
const prevStatus = React.useRef(authStatus)
const shouldRedirect = !['initial', 'loading', allowedAuthStatus].includes(authStatus)
React.useEffect(() => {
if (shouldRedirect) {
const timerId = setTimeout(() => router.push(redirectUrl), REDIRECT_DELAY)
return () => {
clearTimeout(timerId)
}
}
}, [shouldRedirect, redirectUrl])
React.useEffect(() => {
if (prevStatus.current === 'initial' && authStatus === 'loading') {
setFirstLoad(true)
return () => {
setFirstLoad(false)
}
}
prevStatus.current = authStatus
}, [status])
if (authStatus === 'initial') return null
if (firstLoad) return <p aria-live="polite">Loading...</p>
if (shouldRedirect) {
return (
<p>
<span>
{authStatus}!
</span>
Redirecting to <i>{redirectUrl}</i>...
</p>
)
}
return <React.Fragment>{children}</React.Fragment>
}
export default AuthGuard
