Great! Now we have the session information stored in the nextbnb_session
cookie
Now I want to get the cookie value from the server on the first page load we do, and we store the login state.
Remember the store.js
file we created in the previous module?
Add a new store value:
export default createStore({
login: {
loggedIn: false,
setLoggedIn: action((state) => {
state.loggedIn = true
}),
},
modals: {
//...
Now we need to add some code to pages/index.js
and pages/houses/[id].js
, the 2 entry points.
In pages/index.js
:
//at the top
import Cookies from 'cookies'
//at the bottom
export async function getServerSideProps({ req, res, query }) {
const cookies = new Cookies(req, res)
const nextbnb_session = cookies.get('nextbnb_session')
return {
props: {
nextbnb_session: nextbnb_session || null,
},
}
}
This makes the nextbnb_session
prop available in the component.
We use useEffect
now to check if this prop is available, and if so, we are going to call the setLoggedIn
state action:
//at the top
import { useStoreActions } from 'easy-peasy'
import { useEffect } from 'react'
//...
export default function Home({ nextbnb_session }) {
const setLoggedIn = useStoreActions((actions) => actions.login.setLoggedIn)
useEffect(() => {
if (nextbnb_session) {
setLoggedIn(true)
}
}, [])
//...
We do the same in pages/houses/[id].js
. Here is the full code of the component:
import Head from 'next/head'
import houses from '../../houses.js'
import Layout from '../../components/Layout'
import DateRangePicker from '../../components/DateRangePicker'
import { useState, useEffect } from 'react'
import { useStoreActions } from 'easy-peasy'
import Cookies from 'cookies'
const calcNumberOfNightsBetweenDates = (startDate, endDate) => {
const start = new Date(startDate) //clone
const end = new Date(endDate) //clone
let dayCount = 0
while (end > start) {
dayCount++
start.setDate(start.getDate() + 1)
}
return dayCount
}
export default function House({ house, nextbnb_session }) {
const [dateChosen, setDateChosen] = useState(false)
const [numberOfNightsBetweenDates, setNumberOfNightsBetweenDates] = useState(
0
)
const setShowLoginModal = useStoreActions(
(actions) => actions.modals.setShowLoginModal
)
const setLoggedIn = useStoreActions((actions) => actions.login.setLoggedIn)
useEffect(() => {
if (nextbnb_session) {
setLoggedIn(true)
}
}, [])
return (
<Layout
content={
<div className='container'>
<Head>
<title>{house.title}</title>
</Head>
<article>
<img src={house.picture} width='100%' alt='House picture' />
<p>
{house.type} - {house.town}
</p>
<p>{house.title}</p>
</article>
<aside>
<h2>Choose a date</h2>
<DateRangePicker
datesChanged={(startDate, endDate) => {
setNumberOfNightsBetweenDates(
calcNumberOfNightsBetweenDates(startDate, endDate)
)
setDateChosen(true)
}}
/>
{dateChosen && (
<div>
<h2>Price per night</h2>
<p>${house.price}</p>
<h2>Total price for booking</h2>
<p>${(numberOfNightsBetweenDates * house.price).toFixed(2)}</p>
<button
className='reserve'
onClick={() => {
setShowLoginModal()
}}
>
Reserve
</button>{' '}
</div>
)}
</aside>
<style jsx>{`
.container {
display: grid;
grid-template-columns: 60% 40%;
grid-gap: 30px;
}
aside {
border: 1px solid #ccc;
padding: 20px;
}
`}</style>
</div>
}
/>
)
}
export async function getServerSideProps({ req, res, query }) {
const { id } = query
const cookies = new Cookies(req, res)
const nextbnb_session = cookies.get('nextbnb_session')
return {
props: {
house: houses.filter((house) => house.id === parseInt(id))[0],
nextbnb_session: nextbnb_session || null,
},
}
}
Now we need to change components/Header.js
to show a “Logged in” state in the header instead of the links to login and signup.
We first import
import { useStoreState, useStoreActions } from 'easy-peasy'
and inside the component we define
const loggedIn = useStoreState((state) => state.login.loggedIn)
const setLoggedIn = useStoreActions((actions) => actions.login.setLoggedIn)
Finally we add this JSX:
{
loggedIn ? (
<nav>
<ul>
<li>
<a>Logged in</a>
</li>
</ul>
</nav>
) : (
<nav>
<ul>
<li>
<a href='#' onClick={() => setShowRegistrationModal()}>
Sign up
</a>
</li>
<li>
<a href='#' onClick={() => setShowLoginModal()}>
Log in
</a>
</li>
</ul>
</nav>
)
}
The code for this lesson is available at https://github.com/flaviocopes/airbnb-clone-react-nextjs-2020/tree/5-5