In this activity we will create a CMS (Content Management System) that allows users to upload blog posts. Users will also be able to view blog posts by other authors and filter them based on category. We will use the Context API to manage the application state globally, adhering to a design pattern that closely follows Redux. Although very complex applications may have several stores, we are going to keep it simple and store all stateful data in a single global store.
-
Open the Unsolved folder and install dependencies by running
npm install
at the project root. -
Open another tab in your terminal and run
mongod
. -
Start the app by running
npm start
from the project root. -
Once the app starts open your browser to localhost:3000.
-
Open App.js.
-
There are 4 main sections in this application:
-
A section that allows you to create new posts.
-
A section that lists all of the posts.
-
A detail page to view the contents of an individual post.
-
(BONUS): A Favorites page that lists all of your favorite posts.
-
-
Set up a store for your application with support for the following actions:
-
UPDATE_POSTS: Updates the state with the latest posts.
-
ADD_POST: Adds a post to the posts array.
-
REMOVE_POST: Removes a specified post from your posts array.
-
SET_CURRENT_POST: Sets the current post in the store. This action will only be dispatched from the detail page.
-
SAVING: Defines whether or not a post is in the process of being saved to the database.
-
-
Since this application is larger than our previous applications, we are going to create a separate file for our action types. By doing this, we will be able to import the actions into any component we would like, thus reducing the chance of mispelling them thanks to the autocomplete feature in our IDE.
-
In
client/src/utils
, create a file namedactions.js
. -
Inside the actions file, export a
const
for each action type so that you will be able to easily import it into whichever file you would like.- Ex:
export const GET_POSTS = "GET_POSTS";
- Ex:
-
In
client/src/utils/GlobalState.js
, create a store for your application with with a reducer that can handle each action type. -
Export a
StoreProvider
anduseStoreContext
Hook. -
In
App.js
, wrap your entire application with theStoreProvider
.
-
Open up
client/src/components/CreatePostForm
and add the functionality for creating new posts. -
Open up
client/src/components/PostsList
and add the functionality for getting the latest posts and deleting a single post. -
Open up
client/src/pages/Detail.js
and add the functionality for viewing a selected post. -
📝 With every API call, dispatch the
LOADING
action. Then make the API call. Dispatch your action within thethen
method. -
Update the
UPDATE_POSTS
,SET_CURRENT_POST
, andADD_POST
action handlers so that theloading
property on the state changes tofalse
. -
In
client/src/components/Nav
, use the global store to make theLoading...
text appear whenever the global state is loading. -
In
client/src/components/CreatePostForm
, update the submit button so that it isdisabled
if the global state is loading.
-
In
client/src/pages/Detail.js
, add a❤️ Add to Favorites
button that adds the blog post to afavorites
array in the store. -
Here are some actions you might choose to use:
-
UPDATE_FAVORITES: Updates the state with the latest favorites.
-
ADD_FAVORITE: Adds a favorite to the favorites array.
-
REMOVE_FAVORITE: Removes a specified post from your favorites list.
-
-
You will not have to modify any files that are not in the
client
folder. -
If you are stuck or running into errors, try to
console.log
theaction
in your store. Try to make sure that the reducer is functioning as expected before looking at your component. -
Use the
utils/GlobalState.js
file from the previous activity to help scaffold the store. -
Ask the instructor or a TA if you're having difficulty understanding any of the activity requirements.