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:

Client folder 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 h2 {
    margin-bottom: 10px;
    color: #333;
}
 
.product-card p {
    color: #666;
}
 
.product-card h3 {
    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;
 
 
}
 
h1 {
    text-align: center;
    background-color: rgb(8, 149, 8);
    color: white;
    width: 70vw;
    padding: 5px;
    border-radius: 10px;
    font-size: larger;
    margin: 20px;
}
 
h2 {
    text-align: center;
    margin-bottom: -5px;
    margin-top: -5px;
}
 
h3 {
    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.

Output Preview

Similar Reads

Prerequisites:

React JS MongoDB Express Node JS MERN Stack...

Approach to create Product Review Platform:

State and Components: Uses useState for products and newProduct. Renders product cards, reviews, and forms. API Interaction: Fetches products on mount. Utilizes Axios for CRUD operations. Product Operations: Adds new products. Deletes products. Submits and displays reviews. User Interface: Forms for input. Dynamically updates UI....

Steps to Create the Frontend:

Step 1: Set up React frontend using the command....

Steps to Create the Backend:

...