Steps to Create the Frontend
Step 1: Set up React frontend using the command.
npx create-react-app client
Step 2: Navigate to the project folder using the command.
cd client
Step 3: Install axios
npm i axios
Project Structure:
The updated dependencies in package.json for frontend will look like:
"dependencies": {
"axios": "^1.5.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Example: Below is the client code.
Javascript
import React, { useState, useEffect } from "react" ; import axios from "axios" ; import "./App.css" ; const App = () => { const [products, setProducts] = useState([]); const [newProduct, setNewProduct] = useState({ name: "" , description: "" , image: "" , }); useEffect(() => { // Fetch products from the server axios .get( "http://localhost:5000/api/products" ) .then((response) => setProducts(response.data)) . catch ((error) => console.error(error)); }, []); const handleReviewSubmit = (productId, review) => { // Submit a new review for a product axios .post( `http: //localhost:5000/api/products/${productId}/review`, review) .then((response) => { // Update the products in the state with the new review const updatedProducts = products.map((product) => product._id === productId ? response.data : product ); setProducts(updatedProducts); }) . catch ((error) => console.error(error)); }; const handleAddProduct = () => { // Submit a new product console.log( "i am called" ); axios .post( "http://localhost:5000/api/products" , newProduct) .then((response) => { // Update the products in the state with the new product setProducts([...products, response.data]); // Clear the newProduct state for the next entry setNewProduct({ name: "" , description: "" , image: "" }); }) . catch ((error) => console.error(error)); }; const handleProductDelete = (productId) => { // Send a DELETE request to the server axios . delete (`http: //localhost:5000/api/products/${productId}`) .then((response) => { // Update the products in the state after successful deletion console.log( "The Producted deleted successfully was:" , response.data.deletedProduct ); const updatedProducts = products.filter( (product) => product._id !== productId ); setProducts(updatedProducts); }) . catch ((error) => console.error( `Error deleting product with ID ${productId}:`, error) ); }; return ( <div className= "outer-cont" > <h1 style={ { marginTop: "10px" , color: "white" }}> GFG </h1> <h2>Product Review Platform</h2> <div className= "add-container" > <h3>Add a New Product:</h3> <form onSubmit={(e) => { e.preventDefault(); handleAddProduct(); }}> <label> Name:{ " " } <input type= "text" name= "name" value={newProduct.name} onChange={(e) => setNewProduct( { ...newProduct, name: e.target.value } ) } required /> </label> <label> Description:{ " " } <input type= "text" name= "description" value={newProduct.description} onChange={(e) => setNewProduct( { ...newProduct, description: e.target.value } ) } required /> </label> <label> { " " } Image URL:{ " " } <input type= "text" name= "image" value={newProduct.image} onChange={(e) => setNewProduct( { ...newProduct, image: e.target.value }) } required /> </label> <button className= "add-btn" type= "submit" > Add Product </button> </form> </div> <div className= "cards" > {products.map((product) => ( <div key={product._id} className= "product-card" > <h2>{product.name}</h2> <button className= "delete-btn" onClick={ () => handleProductDelete(product._id) }> Delete Product </button> <img src={product.image} style={{ width: "300px" }} alt= "" /> <p>{product.description}</p> <h3>Reviews:</h3> <ul> {product.reviews.map((review, index) => ( <li key={index}> <strong>{review.user}</strong> - {review.rating}/5:{ " " } {review.comment} </li> ))} </ul> <h3>Add a Review:</h3> <form onSubmit={(e) => { e.preventDefault(); const user = e.target.elements.user.value; const rating = e.target.elements.rating.value; const comment = e.target.elements.comment.value; handleReviewSubmit(product._id, { user, rating, comment }); }}> <label> User: <input type= "text" name= "user" required /> </label> <label> Rating:{ " " } <input type= "number" name= "rating" min= "1" max= "5" required /> </label> <label> Comment: <textarea name= "comment" required> </textarea> </label> <button type= "submit" > Submit Review </button> </form> </div> ))} </div> </div> ); }; export default App; |
CSS
body { font-family : 'Arial' , sans-serif ; margin : 0 ; padding : 0 ; } .app-container { text-align : center ; } .product-card { border : 1px solid #ddd ; border-radius: 11px ; box-shadow: 0 8px 35px rgba( 0 , 0 , 0 , 0.1 ); padding : 10px ; margin : 11px ; width : 300px ; } .product-card h 2 { margin-bottom : 10px ; color : #333 ; } .product-card p { color : #666 ; } .product-card h 3 { margin : 10px 0 ; color : #333 ; } .product-card ul { list-style-type : none ; padding : 0 ; } .product-card ul li { margin-bottom : 2px ; color : #555 ; } .product-card form { margin-top : 10px ; } .product-card label { display : block ; margin-bottom : 5px ; color : #333 ; gap: 10px ; } .product-card input, .product-card textarea { width : 100% ; padding : 3px ; margin-bottom : px; box-sizing: border-box; } label { margin : 10px ; } .product-card button { background-color : #007BFF ; color : #fff ; border : none ; padding : 10px ; cursor : pointer ; border-radius: 4px ; } .product-card button:hover { background-color : #0056b3 ; } @media ( max-width : 600px ) { .product-card { width : 100% ; } } .cards { display : flex; flex-wrap: wrap; justify- content : space-around; max-width : 1200px ; margin : 20px auto ; } .delete-btn { background-color : red ; color : white ; margin-bottom : 15px ; } .add-container { display : flex; flex- direction : column; justify- content : center ; align-items: center ; } h 1 { text-align : center ; background-color : rgb ( 8 , 149 , 8 ); color : white ; width : 70 vw; padding : 5px ; border-radius: 10px ; font-size : larger ; margin : 20px ; } h 2 { text-align : center ; margin-bottom : -5px ; margin-top : -5px ; } h 3 { color : #007BFF ; } .outer-cont { display : flex; flex- direction : column; justify- content : center ; align-items: center ; } .add-btn { background-color : rgb ( 8 , 149 , 8 ); color : #121010 ; margin-left : 5px ; border : none ; padding : 5px 10px ; border-radius: 10px ; } img { width : 200px ; height : 200px ; } |
Step to Run Your React App
npm start
Your React app should now be running at http://localhost:3000. It displays a form for adding new products and a list of existing products with their reviews.
Product Review Platform using MERN
In this article, we’ll walk through creating a Product Review Platform using the MERN stack (MongoDB, Express.js, React, and Node). By the end of this guide, you’ll have a functional application where users can add products, leave reviews, and delete products.
Preview of final output: Let us have a look at how the final output will look like.