Update README.md

parent a80c60ec
...@@ -57,10 +57,10 @@ my-product-management-system/ ...@@ -57,10 +57,10 @@ my-product-management-system/
├── src/ ├── src/
│ ├── components/ │ ├── components/
│ │ ├── Category/ │ │ ├── Category/
│ │ │ ├── CategoryListClass.js
│ │ │ ├── CategoryFormClass.js │ │ │ ├── CategoryFormClass.js
│ │ │ ├── CategoryListFunction.js │ │ │ ├── CategoryListClass.js
│ │ │ ├── CategoryFormFunction.js │ │ │ ├── CategoryFormFunction.js
│ │ │ ├── CategoryListFunction.js
│ │ │ ├── Category.css │ │ │ ├── Category.css
│ │ ├── Product/ │ │ ├── Product/
│ │ │ ├── ProductListClass.js │ │ │ ├── ProductListClass.js
...@@ -78,90 +78,386 @@ my-product-management-system/ ...@@ -78,90 +78,386 @@ my-product-management-system/
└── ... └── ...
``` ```
### 4. Creating Class Components (30 minutes) ### 5. Creating Class Components (30 minutes)
- Deep dive into creating class components. - Deep dive into creating class components.
- Create `CategoryFormClass.js` and `CategoryListClass.js` as class components. - Create `CategoryFormClass.js` and `CategoryListClass.js` as class components.
- Discuss state management, event handling, and lifecycle methods. - Discuss state management, event handling, and lifecycle methods.
CategoryFormClass.js
CategoryFormClass.js
```jsx
##### I: Importing Dependencies
Start by importing React and any necessary services:
```
import React, { Component } from 'react'; import React, { Component } from 'react';
import { createCategory } from '../../services/ApiCategory'; ```
#### II: Defining the Class Component
```
class CategoryFormClass extends Component { class CategoryFormClass extends Component {
state = { state = {
name: '', name: '',
description: '' description: ''
}; };
render() {
return (
"test"
);
}
}
```
handleChange = (event) => { #### III: Exporting the Component
this.setState({ [event.target.name]: event.target.value });
};
handleSubmit = async (event) => { ```
export default CategoryFormClass;
```
#### IV: Handling Input Changes & Submit Function
```
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
handleSubmit = (event) => {
event.preventDefault(); event.preventDefault();
const { name, description } = this.state; const { name, description } = this.state;
await createCategory({ name, description }); console.log(this.state);
this.setState({ name: '', description: '' }); alert(`Category Name: ${name}\nCategory Description: ${description}`);
this.props.fetchCategories();
};
render() { this.setState({ name: "", description: "" });
const { name, description } = this.state
return ( // Call the addCategory method passed down from CategoryListClass
<form onSubmit={this.handleSubmit}> // this.props.addCategory({ name, description });
<input // API integration will be handled in the next chapter
type="text" // await createCategory({ name, description });
name="name" // this.props.fetchCategories();
value={name} };
onChange={this.handleChange}
placeholder="Category Name" ```
/> ```
<input // handleSubmit = (event) => {
type="text" // event.preventDefault();
name="description" // const { name, description } = this.state;
value={description} // console.log(this.state);
onChange={this.handleChange} // alert(`Category Name: ${name}\nCategory Description: ${description}`);
placeholder="Category Description"
/> // this.setState({ name: "", description: "" });
<button type="submit">Add Category</button>
</form> // // Call the addCategory method passed down from CategoryListClass
); // this.props.addCategory({ name, description });
}
// // Call the createCategory function, which uses axios to create a new category
// createCategory({ name, description })
// .then(response => {
// console.log("Category created successfully:", response.data);
// // Optionally, you could call fetchCategories here if you want to refresh the category list
// // this.props.fetchCategories();
// })
// .catch(error => {
// console.error("There was an error creating the category:", error);
// });
// };
```
#### V: Rendering the Form
```
render() {
const { name, description } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
name="name"
value={name}
onChange={this.handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={description}
onChange={this.handleChange}
placeholder="Category Description"
/>
<button type="submit">Add Category</button>
</form>
);
} }
export default CategoryFormClass;
``` ```
<details>
<summary>full code</summary>
```jsx
import React, { Component } from 'react';
import { createCategory } from '../../services/ApiCategory';
class CategoryFormClass extends Component {
state = {
name: '',
description: ''
};
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
handleSubmit = async (event) => {
event.preventDefault();
const { name, description } = this.state;
await createCategory({ name, description });
this.setState({ name: '', description: '' });
this.props.fetchCategories();
};
render() {
const { name, description } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<input
type="text"
name="name"
value={name}
onChange={this.handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={description}
onChange={this.handleChange}
placeholder="Category Description"
/>
<button type="submit">Add Category</button>
</form>
);
}
}
export default CategoryFormClass;
```
</details>
CategoryListClass.js CategoryListClass.js
```jsx
#### I: Importing Dependencies
Start by importing React and any necessary services:
```
import React, { Component } from 'react'; import React, { Component } from 'react';
import CategoryFormClass from './CategoryFormClass';
import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory';
import './Category.css'; import './Category.css';
import CategoryFormClass from './CategoryFormClass';
// import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory';
```
#### II: Defining the Class Component and Initial State
```
class CategoryListClass extends Component { class CategoryListClass extends Component {
state = { state = {
categories: [], categories: [
// Hardcoded categories for initial testing
{ id: 1, name: "Electronics", description: "Devices and gadgets" },
{ id: 2, name: "Books", description: "Various books and literature" },
],
isEditing: false, isEditing: false,
currentCategory: { id: '', name: '', description: '' }, currentCategory: { id: "", name: "", description: "" },
}; };
componentDidMount() { render() {
this.fetchCategories(); return "test";
} }
}
```
#### III: Lifecycle Method and Fetch Categories
```
componentDidMount() {
// this.fetchCategories();
}
fetchCategories = async () => {
// const categories = await getCategories();
// this.setState({ categories });
};
fetchCategories = async () => {
const categories = await getCategories(); ```
this.setState({ categories });
#### IV: Handling Delete, Edit, and Cancel Edit
```
handleDelete = (id) => {
const filteredCategories = this.state.categories.filter(category => category.id !== id);
this.setState({ categories: filteredCategories });
console.log(id);
alert(`Deleted Id: ${id}`);
// await deleteCategory(id);
// this.fetchCategories();
};
handleEdit = (category) => {
this.setState({ isEditing: true, currentCategory: category });
};
handleCancelEdit = () => {
this.setState({ isEditing: false, currentCategory: { id: '', name: '', description: '' } });
};
```
#### V: Handling Input Changes and Update and Add using props
```
handleChange = (event) => {
const { name, value } = event.target;
this.setState((prevState) => ({
currentCategory: { ...prevState.currentCategory, [name]: value }
}));
};
handleUpdate = (event) => {
event.preventDefault();
const { categories, currentCategory } = this.state;
const updatedCategories = categories.map((category) =>
category.id === currentCategory.id ? { ...currentCategory } : category
);
this.setState({
categories: updatedCategories,
isEditing: false,
currentCategory: { id: "", name: "", description: "" },
});
alert(`Category Name: ${currentCategory.name}\nCategory Description: ${currentCategory.description}`);
console.log(this.state);
// await updateCategory(currentCategory.id, { name: currentCategory.name, description: currentCategory.description });
// this.fetchCategories();
};
addCategory = (newCategory) => {
this.setState((prevState) => ({
categories: [...prevState.categories, { id: prevState.categories.length + 1, ...newCategory }],
}));
};
```
#### VI: Rendering the Component
```
render() {
const { categories, isEditing, currentCategory } = this.state;
return (
<div>
<h2>Categories</h2>
{isEditing ? (
<form onSubmit={this.handleUpdate}>
<input
type="text"
name="name"
value={currentCategory.name}
onChange={this.handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={currentCategory.description}
onChange={this.handleChange}
placeholder="Category Description"
/>
<button type="submit" className="button button-update">Update</button>
<button type="button" className="button button-delete" onClick={this.handleCancelEdit}>Cancel</button>
</form>
) : (
<CategoryFormClass addCategory={this.addCategory} />
// <CategoryFormClass fetchCategories={this.fetchCategories} />
)}
<div style={{ display: "inline-block", textAlign: "left", marginTop: "20px"}}>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{categories.map(category => (
<tr key={category.id}>
<td>{category.id}</td>
<td>{category.name}</td>
<td>{category.description}</td>
<td>
<button className="button button-update" onClick={() => this.handleEdit(category)}>Edit</button>
<button className="button button-delete" onClick={() => this.handleDelete(category.id)}>Delete</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
```
#### VI: Exporting the Component
```
export default CategoryListClass;
```
<details>
<summary>full code</summary>
```jsx
import React, { Component } from 'react';
// import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory';
import './Category.css';
import CategoryFormClass from './CategoryFormClass';
class CategoryListClass extends Component {
state = {
categories: [
{ id: 1, name: 'Electronics', description: 'Devices and gadgets' },
{ id: 2, name: 'Books', description: 'Various books and literature' }
],
isEditing: false,
currentCategory: { id: '', name: '', description: '' },
}; };
handleDelete = async (id) => { // componentDidMount() {
await deleteCategory(id); // this.fetchCategories();
this.fetchCategories(); // }
// fetchCategories = async () => {
// const categories = await getCategories();
// this.setState({ categories });
// };
handleDelete = (id) => {
const filteredCategories = this.state.categories.filter(category => category.id !== id);
this.setState({ categories: filteredCategories });
}; };
handleEdit = (category) => { handleEdit = (category) => {
...@@ -179,12 +475,15 @@ class CategoryListClass extends Component { ...@@ -179,12 +475,15 @@ class CategoryListClass extends Component {
})); }));
}; };
handleUpdate = async (event) => { handleUpdate = (event) => {
event.preventDefault(); event.preventDefault();
const { currentCategory } = this.state; const { categories, currentCategory } = this.state;
await updateCategory(currentCategory.id, { name: currentCategory.name, description: currentCategory.description }); const updatedCategories = categories.map(category =>
this.setState({ isEditing: false, currentCategory: { id: '', name: '', description: '' } }); category.id === currentCategory.id
this.fetchCategories(); ? { ...currentCategory }
: category
);
this.setState({ categories: updatedCategories, isEditing: false, currentCategory: { id: '', name: '', description: '' } });
}; };
render() { render() {
...@@ -240,89 +539,518 @@ class CategoryListClass extends Component { ...@@ -240,89 +539,518 @@ class CategoryListClass extends Component {
</div> </div>
); );
} }
} }
export default CategoryListClass;
```
</details>
### 6. Adding CSS (15 minutes)
- Demonstrate how to add and apply CSS in React.
- Style the category and product forms.
Category.css *
```css
form {
margin: 20px;
}
input {
margin-right: 10px;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 18px;
text-align: left;
}
th, td {
padding: 12px 15px;
border: 1px solid #ddd;
}
th {
background-color: #f4f4f4;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f1f1f1;
}
.button {
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
.button-delete {
background-color: #ff4d4d;
}
.button-delete:hover {
background-color: #ff1a1a;
}
.button-update {
background-color:blue;
}
.button-update:hover {
background-color: blue;
}
```
### 7. Integrating MockAPI for CRUD Operations (20 minutes)
- Set up MockAPI for category and product management.
- Perform CRUD operations (Create, Read, Update, Delete) using MockAPI.
- Url Localhost / Mockapi: 'https://66b1b4381ca8ad33d4f4d9c0.mockapi.io/api/v1/category';
- Discuss Axios/ Await Fectch
- **Install React Router:**
```bash
npm install axios --save
```
- ApiCategory.js
```jsx
import axios from 'axios';
const apiUrl = 'https://66b1b4381ca8ad33d4f4d9c0.mockapi.io/api/v1/category';
export const getCategories = () => {
return axios.get(apiUrl)
.then((response) => response.data);
};
export const createCategory = (category) => {
return axios.post(apiUrl, category)
.then((response) => response.data);
};
export const deleteCategory = (id) => {
return axios.delete(`${apiUrl}/${id}`)
.then((response) => response.data);
};
export const updateCategory = (id, category) => {
return axios.put(`${apiUrl}/${id}`, category)
.then((response) => response.data);
};
// Example with custom headers
// export const createCategory = (category, token) => {
// return axios.post(apiUrl, category, {
// headers: {
// Authorization: `Bearer ${token}` // Example of an auth token
// }
// }).then((response) => response.data);
// };
// export const createCategory = (category) =>
// fetch(apiUrl, {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify(category),
// }).then((res) => res.json());
// export const deleteCategory = (id) =>
// fetch(\`\${apiUrl}/\${id}\`, {
// method: 'DELETE',
// }).then((res) => res.json());
// export const updateCategory = (id, category) =>
// fetch(\`\${apiUrl}/\${id}\`, {
// method: 'PUT',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify(category),
// }).then((res) => res.json());
```
### 8. Routing Navigation (15 minutes)
- Discus how React Rauter works
- Modify \`App.js\` to include a welcome message and links to the category and product registration pages.
- Step-by-Step Instructions:
- **Install React Router:**
- Run the following command to install React Router:
```bash
npm install react-router-dom
```
- **Modify App.js:**
- Replace the content of \`App.js\` with the following code:
```jsx
import React from 'react';
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';
import logo from './logo.svg';
import './App.css';
import CategoryListClass from './components/Category/CategoryListClass';
function App() {
return (
<Router>
<div className="App">
<h1>Product Management System</h1>
<nav>
<ul>
<li>
<Link to="/category">Register Category</Link>
</li>
<li>
<Link to="/product">Register Product</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/category" element={<CategoryListClass />} />
<Route path="/product" element={<CategoryListClass />} />
</Routes>
</div>
</Router>
);
}
export default App;
```
### 9. Design Content Navigation (15 minutes)
- Modify \`App.js\` to design topbar,sidebar and contentregistration pages.
- Step-by-Step Instructions:
- **Modify App.js:**
- Replace code to App.js:
```jsx
import logo from './logo.svg';
import './App.css';
import CategoryListClass from './components/Category/CategoryListClass';
import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom';
function App() {
return (
<Router>
<div className="App">
<div className="topbar">
<h1>Product Management System</h1>
</div>
<div className="container">
<nav className="sidebar">
<ul>
<li>
<Link to="/category1">Category</Link>
</li>
<li>
<Link to="/product">Product</Link>
</li>
</ul>
</nav>
<div className="content">
<Routes>
<Route path="/category1" element={<CategoryListClass />} />
{/*<Route path="/product" element={<ProductList />} /> */}
</Routes>
</div>
</div>
</div>
</Router>
);
}
export default App;
export default CategoryListClass;
```
### 5. Creating Functional Components (30 minutes) ```
- **Modify App.css:**
- Add the content of \`App.css\` with the following code:
```css
.App {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: column;
height: 100vh;
}
.topbar {
background-color: #f8f9fa;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 20px;
}
.container {
display: flex;
flex-grow: 1;
}
.sidebar {
width: 200px;
background-color: #f8f9fa;
padding: 15px;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
text-align: left;
}
.sidebar ul {
list-style-type: none;
padding: 0;
}
.sidebar ul li {
margin: 10px 0;
}
.sidebar ul li a {
text-decoration: none;
color: #007bff;
font-weight: bold;
}
.content {
flex-grow: 1;
padding: 40px;
}
```
### 10. Break (5 minutes)
### 11. Creating Functional Components (30 minutes)
- Deep dive into creating functional components with hooks. - Deep dive into creating functional components with hooks.
- Create `CategoryFormFunction.js` and `CategoryListFunction.js` as functional components. - Create `CategoryFormFunction.js` and `CategoryListFunction.js` as functional components.
- Discuss useState and useEffect hooks. - Discuss useState and useEffect hooks.
CategoryFormFunction.js CategoryFormFunction.js
```jsx #### I: Importing Dependencies
Start by importing React and any necessary services:
```
import React, { useState } from 'react'; import React, { useState } from 'react';
import { createCategory } from '../../services/ApiCategory'; //import { createCategory } from '../../services/ApiCategory';
```
const CategoryFormFunction = ({ fetchCategories }) => { #### II: Defining the Functional Component
const [categoryName, setCategoryName] = useState('');
const [description, setDescription] = useState('');
const handleChange = (event) => { ```
const { name, value } = event.target; const CategoryFormFunction = () => {
if (name === 'name') setCategoryName(value); return (
if (name === 'description') setDescription(value); "test"
}; );
};
```
const handleSubmit = async (event) => { #### III: Introducing useState Hook
event.preventDefault(); ```
await createCategory({ name: categoryName, description }); const [categoryName, setCategoryName] = useState('');
setCategoryName(''); const [description, setDescription] = useState('');
setDescription('');
fetchCategories(); ```
};
#### IV: Handling Input Changes & Submit Function
```
const handleChange = (event) => {
const { name, value } = event.target;
if (name === 'name') setCategoryName(value);
if (name === 'description') setDescription(value);
};
```
```
const handleSubmit = (event) => {
event.preventDefault();
// Log the current state values
console.log({
categoryName: categoryName,
description: description,
});
// Display an alert with the submitted category name and description
alert(`Category Name: ${categoryName}\nCategory Description: ${description}`);
// Clear the input fields after submission
setCategoryName('');
setDescription('');
// API integration will be handled in the next chapter
//await createCategory({ name: categoryName, description });
//fetchCategories();
};
```
#### V: Rendering the Form
```
const CategoryFormFunction = () => {
return ( return (
<form onSubmit={handleSubmit}> <form>
<input <input type="text" name="name" placeholder="Category Name" />
type="text" <input type="text" name="description" placeholder="Category Description" />
name="name"
value={categoryName}
onChange={handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={description}
onChange={handleChange}
placeholder="Category Description"
/>
<button type="submit">Add Category</button> <button type="submit">Add Category</button>
</form> </form>
); );
}; };
```
#### VII: Rendering the Form with Function
Start by importing React and any necessary services:
```
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
value={categoryName}
onChange={handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={description}
onChange={handleChange}
placeholder="Category Description"
/>
<button type="submit">Add Category</button>
</form>
);
```
#### VI: Exporting the Component
```
export default CategoryFormFunction; export default CategoryFormFunction;
``` ```
<details>
<summary>full code</summary>
```jsx
import React, { useState } from 'react';
import { createCategory } from '../../services/ApiCategory';
const CategoryFormFunction = ({ fetchCategories }) => {
const [categoryName, setCategoryName] = useState('');
const [description, setDescription] = useState('');
const handleChange = (event) => {
const { name, value } = event.target;
if (name === 'name') setCategoryName(value);
if (name === 'description') setDescription(value);
};
const handleSubmit = async (event) => {
event.preventDefault();
await createCategory({ name: categoryName, description });
setCategoryName('');
setDescription('');
fetchCategories();
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
value={categoryName}
onChange={handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={description}
onChange={handleChange}
placeholder="Category Description"
/>
<button type="submit">Add Category</button>
</form>
);
};
export default CategoryFormFunction;
```
</details>
CategoryListFunction.js CategoryListFunction.js
```jsx
#### I: Importing Dependencies
Start by importing React and any necessary services:
```
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory'; import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory';
import './Category.css'; import './Category.css';
import CategoryFormFunction from './CategoryFormFunction'; import CategoryFormFunction from './CategoryFormFunction';
```
#### II: Defining the Functional Component
```
const CategoryListFunction = () => { const CategoryListFunction = () => {
return (
"testCategory"
);
}
```
#### III: Introducing useState Hook
```
const [categories, setCategories] = useState([]); const [categories, setCategories] = useState([]);
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const [currentCategory, setCurrentCategory] = useState({ id: '', name: '', description: '' }); const [currentCategory, setCurrentCategory] = useState({ id: '', name: '', description: '' });
useEffect(() => { ```
fetchCategories(); #### III: Lifecycle Method and Fetch Categories
}, []);
```
componentDidMount() {
// this.fetchCategories();
}
fetchCategories = async () => {
// const categories = await getCategories();
// this.setState({ categories });
};
const fetchCategories = async () => {
const categories = await getCategories();
setCategories(categories);
};
```
#### IV: Handling Delete, Edit, and Cancel Edit
```
const handleDelete = async (id) => { const handleDelete = async (id) => {
await deleteCategory(id); await deleteCategory(id);
fetchCategories(); fetchCategories(); // Refresh the list after deletion
}; };
const handleEdit = (category) => { const handleEdit = (category) => {
...@@ -335,6 +1063,10 @@ const CategoryListFunction = () => { ...@@ -335,6 +1063,10 @@ const CategoryListFunction = () => {
setCurrentCategory({ id: '', name: '', description: '' }); setCurrentCategory({ id: '', name: '', description: '' });
}; };
```
#### V: Handling Input Changes and Update and Add using props
```
const handleChange = (event) => { const handleChange = (event) => {
const { name, value } = event.target; const { name, value } = event.target;
setCurrentCategory((prevCategory) => ({ setCurrentCategory((prevCategory) => ({
...@@ -354,6 +1086,11 @@ const CategoryListFunction = () => { ...@@ -354,6 +1086,11 @@ const CategoryListFunction = () => {
fetchCategories(); fetchCategories();
}; };
```
#### II: Rendering the Functional Component
```
return ( return (
<div> <div>
<h2>Categories</h2> <h2>Categories</h2>
...@@ -412,120 +1149,134 @@ const CategoryListFunction = () => { ...@@ -412,120 +1149,134 @@ const CategoryListFunction = () => {
</table> </table>
</div> </div>
); );
};
export default CategoryListFunction;
```
### 6. Adding CSS (15 minutes)
- Demonstrate how to add and apply CSS in React.
- Style the category and product forms.
Category.css
```css
form {
margin: 20px;
}
input {
margin-right: 10px;
}
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
font-size: 18px;
text-align: left;
}
th, td {
padding: 12px 15px;
border: 1px solid #ddd;
}
th {
background-color: #f4f4f4;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f1f1f1;
}
.button {
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
.button-delete {
background-color: #ff4d4d;
}
.button-delete:hover {
background-color: #ff1a1a;
}
.button-update {
background-color:blue;
}
.button-update:hover {
background-color: blue;
}
``` ```
<details>
### 7. Break (5 minutes) <summary>full code</summary>
```jsx
### 8. Integrating MockAPI for CRUD Operations (30 minutes) import React, { useEffect, useState } from 'react';
- Set up MockAPI for category and product management. import { getCategories, deleteCategory, updateCategory } from '../../services/ApiCategory';
- Perform CRUD operations (Create, Read, Update, Delete) using MockAPI. import './Category.css';
- Url Localhost / Mockapi: 'https://66b1b4381ca8ad33d4f4d9c0.mockapi.io/api/v1/category'; import CategoryFormFunction from './CategoryFormFunction';
- Discuss Axios/ Await Fectch
const CategoryListFunction = () => {
ApiCategory.js const [categories, setCategories] = useState([]);
const [isEditing, setIsEditing] = useState(false);
```jsx const [currentCategory, setCurrentCategory] = useState({ id: '', name: '', description: '' });
const apiUrl = 'https://mockapi.io/endpoint';
useEffect(() => {
export const getCategories = () => fetch(apiUrl).then((res) => res.json()); fetchCategories();
}, []);
export const createCategory = (category) =>
fetch(apiUrl, { const fetchCategories = async () => {
method: 'POST', const categories = await getCategories();
headers: { setCategories(categories);
'Content-Type': 'application/json', };
},
body: JSON.stringify(category), const handleDelete = async (id) => {
}).then((res) => res.json()); await deleteCategory(id);
fetchCategories();
export const deleteCategory = (id) => };
fetch(\`\${apiUrl}/\${id}\`, {
method: 'DELETE', const handleEdit = (category) => {
}).then((res) => res.json()); setIsEditing(true);
setCurrentCategory(category);
export const updateCategory = (id, category) => };
fetch(\`\${apiUrl}/\${id}\`, {
method: 'PUT', const handleCancelEdit = () => {
headers: { setIsEditing(false);
'Content-Type': 'application/json', setCurrentCategory({ id: '', name: '', description: '' });
}, };
body: JSON.stringify(category),
}).then((res) => res.json()); const handleChange = (event) => {
``` const { name, value } = event.target;
setCurrentCategory((prevCategory) => ({
### 9. Task to Create Product Page (60 minutes) ...prevCategory,
[name]: value,
}));
};
const handleUpdate = async (event) => {
event.preventDefault();
await updateCategory(currentCategory.id, {
name: currentCategory.name,
description: currentCategory.description,
});
setIsEditing(false);
setCurrentCategory({ id: '', name: '', description: '' });
fetchCategories();
};
return (
<div>
<h2>Categories</h2>
{isEditing ? (
<form onSubmit={handleUpdate}>
<input
type="text"
name="name"
value={currentCategory.name}
onChange={handleChange}
placeholder="Category Name"
/>
<input
type="text"
name="description"
value={currentCategory.description}
onChange={handleChange}
placeholder="Category Description"
/>
<button type="submit" className="button button-update">
Update
</button>
<button type="button" className="button button-delete" onClick={handleCancelEdit}>
Cancel
</button>
</form>
) : (
<CategoryFormFunction fetchCategories={fetchCategories} />
)}
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{categories.map((category) => (
<tr key={category.id}>
<td>{category.id}</td>
<td>{category.name}</td>
<td>{category.description}</td>
<td>
<button className="button button-update" onClick={() => handleEdit(category)}>
Edit
</button>
<button className="button button-delete" onClick={() => handleDelete(category.id)}>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default CategoryListFunction;
```
</details>
### 12. Task to Create Product Page (60 minutes)
- Follow category page, task to create product registration page. Can use class / functional component - Follow category page, task to create product registration page. Can use class / functional component
- Link forms to MockAPI for data submission. - Link forms to MockAPI for data submission.
- Url localhost / Mockapi: 'https://66b1b4381ca8ad33d4f4d9c0.mockapi.io/api/v1/product'; - Url localhost / Mockapi: 'https://66b1b4381ca8ad33d4f4d9c0.mockapi.io/api/v1/product';
- Implement similar logic for \`ProductForm.js\` & \`ProductList.js\` - Implement similar logic for \`ProductForm.js\` & \`ProductList.js\`
Example form and list structure with API integration
```jsx ```jsx
import React, { Component } from 'react'; import React, { Component } from 'react';
...@@ -548,163 +1299,9 @@ class ProductList extends Component { ...@@ -548,163 +1299,9 @@ class ProductList extends Component {
} }
export default ProductList; export default ProductList;
``` ```
### 10. Routing Navigation (15 minutes)
- Discus how React Rauter works
- Modify \`App.js\` to include a welcome message and links to the category and product registration pages.
- Step-by-Step Instructions:
- **Install React Router:**
- Run the following command to install React Router:
```bash
npm install react-router-dom
```
- **Modify App.js:**
- Replace the content of App.js with the following code:
```jsx
import React from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import logo from './logo.svg';
import './App.css';
import CategoryListClass from './components/Category/CategoryListClass';
import CategoryFormClass from './components/Category/CategoryFormClass';
import CategoryListFunction from './components/Category/CategoryListFunction';
function App() {
return (
<Router>
<div className="App">
<h1>Product Management System</h1>
<nav>
<ul>
<li>
<Link to="/category">Register Category</Link>
</li>
<li>
<Link to="/product">Register Product</Link>
</li>
</ul>
</nav>
<Route path="/category" component={CategoryFormClass} />
<Route path="/product" component={CategoryListFunction} />
</div>
</Router>
);
}
export default App;
```
### 11. Design Content Navigation (15 minutes)
- Modify \`App.js\` to design topbar,sidebar and contentregistration pages.
- Step-by-Step Instructions:
- **Modify App.js:**
- Replace code to App.js:
```jsx
function App() {
return (
<Router>
<div className="App">
<div className="topbar">
<h1>Product Management System</h1>
</div>
<div className="container">
<nav className="sidebar">
<ul>
<li>
<Link to="/category1">Category Class</Link>
</li>
<li>
<Link to="/category2">Category Functional</Link>
</li>
<li>
<Link to="/product">Product</Link>
</li>
</ul>
</nav>
<div className="content">
<Routes>
<Route path="/category1" element={<CategoryListClass />} />
<Route path="/category2" element={<CategoryListFunction />} />
<Route path="/product" element={<ProductList />} />
</Routes>
</div>
</div>
</div>
</Router>
);
}
```
- **Modify App.css:**
- Add the content of \`App.css\` with the following code:
```css
.App {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: column;
height: 100vh;
}
.topbar {
background-color: #f8f9fa;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 20px;
}
.container {
display: flex;
flex-grow: 1;
}
.sidebar {
width: 200px;
background-color: #f8f9fa;
padding: 15px;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
text-align: left;
}
.sidebar ul {
list-style-type: none;
padding: 0;
}
.sidebar ul li {
margin: 10px 0;
}
.sidebar ul li a {
text-decoration: none;
color: #007bff;
font-weight: bold;
}
.content {
flex-grow: 1;
padding: 40px;
}
```
## Conclusion (15 minutes) ## Conclusion (15 minutes)
- Recap the key concepts covered. - Recap the key concepts covered.
- Q&A session to address any doubts or questions. - Q&A session to address any doubts or questions.
...@@ -753,5 +1350,5 @@ export default ProductList; ...@@ -753,5 +1350,5 @@ export default ProductList;
This comprehensive 3-hour training module ensures that students gain an in-depth understanding of React components, styling, and CRUD operations, with ample time for hands-on practice and advanced topics. This comprehensive 4-hour training module ensures that students gain an in-depth understanding of React components, styling, and CRUD operations, with ample time for hands-on practice and advanced topics.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment