Frontend Serverless with React and GraphQL
Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.
24. Add a MyRecipes Page
Objective: Add a MyRecipes page so we can see the list of recipes that we created.
Now that we have a useFetchUser
hook, we can really start diving in and creating components that will only be available to logged in users. While we will get to the create, update, and delete recipe components soon, let's start off with a <MyRecipes>
component to use the <RecipesList>
component that we just created.
Create a new my-recipes
folder within pages and create an index.tsx file in it. This will create a route at /my-recipes
. The component will look quite similar to the index.tsx file that is in the pages
folder except that we use our new useFetchUser
hook. If the hook is loading, we will return the <Loading>
but otherwise, it will pull the sub property off the user object that it receives from fetching the user. In the event that the user isn't logged in, we won't get anything back from trying to pull this sub property off user and we will set owner to be equal to an empty string.
Once we have the owner string, we are ready to create the options object that <RecipesList>
will use to pull the recipes query with a search parameter of owner. This means that the backend will find all of the recipes where the owner field equals the string that we are passing in.
pages/my-recipes/index.tsx
import styled from 'styled-components';import { MainLayout } from '../../components/layout/MainLayout';import { RecipesList, queryEnum } from '../../components/RecipesList';import { Col, Row } from 'antd';import { useFetchUser } from '../../utils/user';import * as _ from 'lodash';import Router from 'next/router';import { Loading } from '../../components/notify/Loading';const StyledRow = styled(Row)`${({ theme }) => `padding: ${theme['padding-small']} ${theme['padding-small']};display: flex;h1 {padding-left: ${theme['padding-small']};text-align: left;}`}`;const Index = () => {const { user, loading: isFetchUser } = useFetchUser();const owner = _.get(user, 'sub');const options = owner ? { variables: { where: { owner } } } : {};if (isFetchUser) return <Loading />;if (!user) {Router.replace('/');}return (<MainLayout title="My Recipes"><StyledRow><Col><h1>My Recipes</h1></Col></StyledRow><RecipesListoptions={options}parentRoute="my-recipes"queryType={queryEnum.recipes}/></MainLayout>);};export default Index;
Once we finish this component, we can add a new button in the navbar that will be called My Recipes. Update the <MainNavbar />
to have this new button and then test the button to verify that you are redirected to the /my-recipes
route. For now, you should see an empty list since we are not logged in yet.