- Create the backend folder.
- Create the a file a named it server.js this is the entry file of the backend application. It's where we are going to register the express app.
- Create the package.json file inside the backend folder with:
npm init -y
- Install the express package to be able to create an express app.
- Create the routes folder which will have inside all the app's routes.
- Create the workouts.js file inside the routes folder.
- Use express.Router() inside workouts.js
- Edit server.js routes with the use of workoutsRoutes const.
- Create all the handlers (get,post,delete,update) inside the workouts.js
- Edit server.js file adding a middleware express.json() which attach the body (data) of a request if it exist to the request object of the handler.
- Edit the .env file to configure the mongo database URI.
- Install the mongoose package. Mongoose is a ODM library. It wraps mongodb with a extra layer tha allows to use methods to read and write database documents, allows to declare modules and schemas. It adds a extra layer of structure that the mongodb by itself doesn't provide.
- I gonna use mongoose to connect it to the database inside the server.js file.
- Import mongoose to use that object to create the connection to the database.
- Inside the backend folder create the model folder and inside it create the workoutModel.js file which will contain the Schema & Model. This schema and model fucntion will be provided by mongoose because mongo by itself is schemeless.
- The schema define the structure a particular document in the database, and the model apply that schema to a particular model and We use that model to interact with a collection of that name.
- Edit routes > workout.js import the workoutModel.js from models > workoutModel.js and edit the POST controller to extract the variables attached to the req.body object and use the model to interact with.
- Create a folder inside backend named controller and inside it a file named workoutController.js.
- Inside workoutController.js I gonna created a bunch of functions that are going to be use or called in the router > workouts.js
- I cutted the call of the workoutModel.js from routes > workout.js and pasted it to workoutController.js because here is where it's gonna be nedded now.
- Edit the workoutController.js to create the GET,POST,DELETE,UPDATE handlers of /api/workouts entry point.
- In the GET a single workout function I have to check if the id is a valid mongoose type objectId so I have to import mongoose en the file to create that validation inside the function.
- Edit the workoutController.js to create the GET,POST,DELETE,UPDATE handlers of /api/workouts entry point.
- In the DELETE a single workout function I have to check if the id is a valid mongoose type objectId so I have to import mongoose in the file to create that validation inside the function.
- Mongoose identify id as _id so in the deleteWorkout function I have to assign the value of id to _id.
- In the PATCH / updateWorkout function I used the spread operator to use whatever is in the req.body to update.
- Move outside the backend folder and type in the console (this will create a react app inside a folder named frontend.)
npx create-react-app frontend
- Inside frontend > src folder I gonna get rid of App.css, App.test.js, logo.svg, reportWebVitals.js, setupTests.js.
- Inside frontedd > src > index.js file erase the import reportWebVitals from './reportWebVitals'; and reportWebVitals(); lines and comments too.
- Inside frontedd > src > App.js file erase the import logo from './logo.svg'; and import './App.css';.
- Leave the App.js function like this:
function App() {
return (
<div className="App">
</div>
);
}
export default App;
- Install the react-router-dom package so I'll can add different pages to this application later, to do that type in console:
npm install react-router-dom
- Import this components from react-route-dom. BrowserRouter, Routes and Route. Browserrouter wraps everywhere I want to use the route, Routes that wraps all the individual Route, and Route that create a single route.
- Create a folder named pages and inside it create a Home.js file which is going to contain a react component which will be imported to App.js and use it in the element prop of the router with this path="/".
- Create a folder named component and inside it create a Navbar.js file which is going to contain a react component which will be imported to App.js and use above the Routes component. In this file I'll imported the Link component to use as anchor tag.
- Import useEffect() and useState() hook inside the Home.js file. The useEffect() hook fires a function when the component is render, if I need to only render once I've to pass a second argument that is a empty array.
- Create a fetch function inside useEffect() hook.
- Map the response from the backend and show every single object of the array in the component.
- Add this code line inside the package.json file to avoid the CORS error. (This indicates that every petition that react doesn't recognize will be proxy to that direction, but in this case that directión is my backend development server.)
"proxy": "http://localhost:400",
- I created a new file in the components folder named WorkoutDetails.js which will be a template for every single workout that is mapped.
- The index.css file was updated.
- The file WorkoutForm.js was created insde the components folder. This will be use to add new workouts to the database.
- Import the WorkoutForm.js component to the Home.js page.
- Update the index.css file.
- Create context folder inside the frontend > src folder.
- Add a new file to context folder and named it WorkoutContext.js
- Import WorkoutContextProvider to the index.js and w 6A4D raps it. So every component in the app has access to this context.
- Create a custom hooks folder inside src.
- Add useWorkoutsContext.js file to hooks folder. This will be use to define where I wanna use the workout context.
- Import the useWorkoutsContext.js tho the Home.js.
- Edit the Home.js file, so I don't goona need the useState hook to update the state instead of that I gonna use the dispatch function.
- Edit the WorkoutForm.js and import the useWorkoutsContext.js to update the UI and keep sync with the database.
- Create a delete button inside WorkoutDetails.js
- Create a span with a handleClick() function that manages the logic necessary to make the request to the database, and keep sync the UI with the database too.
<span
- Create a better error message and highlight input fields to indicate where the error is.
- Edit the createWorkout controller in the backend to handle the errors in a better way.
- Edit the WorkoutForm.js in the frontend to handle the error in the UI.
- Use the emptyFields in the WorkoutForm.js to style the inputs.
- Edit the frontend index.css to highlight the inputs if there is an error.
- Make a trash icon instead of the word "delete" in the WorkoutDetails.js. For that I gonna use material icon from google library.
- Edit the frontend > public > index.html file to insert a link to google material icon.
- Install the package date-fns which is a package to format the date in a more good looking way.
- Import date-fns to WorkoutDetails.js.