Let’s provide a way to log out.
Next to the
<li className='username'>{user}</li>
snippet, I’m going to add this:
<li>
<a
href='#'
onClick={async () => {
await axios.post('/api/auth/logout')
setUser(null)
}}>
Log out
</a>
</li>
which is very similar to the Sign up
and Log in
buttons.
When the Log out button is clicked, it calls the /api/auth/logout
endpoint with a POST request. When the call is over, it resets the session user
property in the frontend, using setUser()
.
We need to define this function, right after the user
declaration:
const setUser = useStoreActions(actions => actions.user.setUser)
Since we use Axios, I’m also going to add
import axios from 'axios'
on top of the file. We already have this library installed.
We also need to add a React fragment to wrap the 2
This should be the full code of the component:
components/Header.js
import Link from 'next/link'
import axios from 'axios'
import { useStoreActions, useStoreState } from 'easy-peasy'
const Header = () => {
const setShowLoginModal = useStoreActions(
actions => actions.modals.setShowLoginModal
)
const setShowRegistrationModal = useStoreActions(
actions => actions.modals.setShowRegistrationModal
)
const user = useStoreState(state => state.user.user)
const setUser = useStoreActions(actions => actions.user.setUser)
return (
<div className='nav-container'>
<Link href='/'>
<a>
<img src='/img/logo.png' alt='' />
</a>
</Link>
<nav>
<ul>
{user ? (
<>
<li className='username'>{user}</li>
<li>
<a
href='#'
onClick={async () => {
await axios.post('/api/auth/logout')
setUser(null)
}}>
Log out
</a>
</li>
</>
) : (
<>
<li>
<a href='#' onClick={() => setShowRegistrationModal()}>
Sign up
</a>
</li>
<li>
<a href='#' onClick={() => setShowLoginModal()}>
Log in
</a>
</li>
</>
)}
</ul>
</nav>
<style jsx>{`
ul {
margin: 0;
padding: 0;
}
li {
display: block;
float: left;
}
a {
text-decoration: none;
display: block;
margin-right: 15px;
color: #333;
}
nav a {
padding: 1em 0.5em;
}
.nav-container {
border-bottom: 1px solid #eee;
height: 50px;
}
img {
float: left;
}
ul {
float: right;
}
.username {
padding: 1em 0.5em;
}
`}</style>
</div>
)
}
export default Header
If you click it now you’ll get an error, because we haven’t defined an /api/auth/logout` server side route.
Let’s do it by adding a this line to our server.js
file:
server.post('/api/auth/logout', (req, res) => {
req.logout()
req.session.destroy()
return res.end(JSON.stringify({ status: 'success', message: 'Logged out' }))
})
We call req.logout()
and req.session.destroy()
, then we send a successful message to the client.
If you try to log out now, you should see that the navigation bar changes back to the normal state.