Open In App

Community Marketplace App using MERN Stack

Last Updated : 07 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Building a community Marketplace App will help you understand the foundational concepts of full-stack development using the MERN(MongoDB, ExpressJS, React, NodeJS) stack. This tutorial will guide you to set up the backend server for the project and demonstrate the integration of frontend functionality with backend setup. This tutorial will teach you how to leverage mongoDB to create and store product profiles.

Output Preview: Let us have a look at how the final output will look like.

Screenshot-2024-03-06-151403

Output

Prerequisites:

Approach to Create Community Marketplace App:

  • Define a functional component named App in ‘App.js‘.
  • Make a list of necessary dependencies and component and import them.
  • Define Nav and ProductList components and wrap them inside in the App components to provide access to shared context data
  • Create Seller.js page with form component.
  • Use React Router to navigate between different pages.
  • Use Axios to fetch data from backend server.
  • Establish connections to the MongoDB database from the backend server using Mongoose or MongoDB native drivers.

Steps to Create a Backend Server:

Step 1: Create a new directory named backend.

mkdir backend
cd backend

Step 2: Create a server using the following command in your terminal.

npm init -y

Step 3: Install the necessary package in your server using the following command.

npm install express mongoose mongodb cors

Project Structure:

Screenshot-2024-03-02-001807

project structure backend

The updated dependencies in package.json file of backend will look like:

"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.3",
"mongodb": "^6.3.0",
"mongoose": "^8.2.0",
}

Step 4: Create a file ‘server.js’ and set up the server.

Javascript




// server.js
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
 
const app = express();
const PORT = process.env.PORT || 5000;
 
// MongoDB connection
mongoose.connect('mongodb://localhost:27017/myapp', {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
    .then(() => console.log('Connected to MongoDB'))
    .catch(err => console.error(err));
 
// Define Product Schema
const productSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    description: String,
    price: {
        type: Number,
        required: true
    },
    category: String,
    imageUrl: String, // Directly store image URL
});
 
const Product = mongoose.model('Product', productSchema);
 
// Middleware for CORS
app.use(cors());
// Middleware for parsing JSON bodies
app.use(express.json());
 
// Route to fetch products
app.get('/product', async (req, res) => {
    try {
        const products = await Product.find();
        res.json(products);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Server Error' });
    }
});
 
// Route to add new product
app.post('/product', async (req, res) => {
    try {
        const { name, description, price, category, imageUrl } = req.body;
        const newProduct = new Product({
            name,
            description,
            price,
            category,
            imageUrl,
        });
        const savedProduct = await newProduct.save();
        res.status(201).json(savedProduct);
    } catch (err) {
        console.error(err);
        res.status(500).json({ message: 'Server Error' });
    }
});
 
// Start the server
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});


Start your server using the following command.

node server.js

Steps to Create the Frontend:

Step 1: Create the frontend repository named client in the main repository.

mkdir client
cd client

Step 2: Create React project using following command.

npx create-react-app .

Step 3: Install necessary dependencies in your application using following command.

npm install axios react-router-dom

Project Structure:

Screenshot-2024-03-02-012937

frontend structure

The updated dependencies in package.json file of frontend will look like:

"dependencies": {
"axios": "^1.6.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Create the files according to the project structure and write the following code.

CSS




/* styles.css */
 
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}
 
.container {
  max-width: 800px;
  margin: 20px auto;
  padding: 0 20px;
}
 
h2 {
  margin-bottom: 20px;
}
 
.product-list {
  list-style: none;
  padding: 0;
}
 
.product-item {
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 10px;
  border-radius: 5px;
}
 
.navbar {
  background-color: #333;
  color: #fff;
  padding: 10px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
 
.navbar-brand {
  margin: 0;
}
 
.nav-links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
}
 
.nav-item {
  margin-right: 10px;
}
 
.nav-link {
  color: #fff;
  text-decoration: none;
}
 
/* Form styles */
.form-input {
  width: 100%;
  padding: 8px;
  margin-bottom: 10px;
  font-size: 16px;
  border-radius: 5px;
  border: 1px solid #ccc;
}
 
.form-submit {
  background-color: #333;
  color: #fff;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
  border-radius: 5px;
}
 
.form-submit:hover {
  background-color: #555;
}
 
 
.product-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
 
.product {
  flex: 1 1 calc(33.33% - 20px);
  border: 1px solid #333;
  padding: 3px;
}
 
.break-line {
  width: 100%;
  margin-top: 20px;
  border: none;
  border-top: 1px solid #ccc;
}
 
 
.product-image {
  width: 300px;
  height: 200px;
  object-fit: cover;
  border-radius: 5px;
}


Javascript




// App.js
import React from 'react';
import {
    BrowserRouter as Router,
    Routes,
    Route
} from 'react-router-dom';
import Nav from './Nav.js';
import ProductList from './ProductList.js';
import Seller from './Seller.js';
import './index.css'
 
const App = () => {
    return (
        <Router>
            <div>
                <Nav />
                <Routes>
                    <Route path="/" element={<ProductList />} />
                    <Route path="/seller" element={<Seller />} />
                </Routes>
            </div>
        </Router>
    );
}
 
export default App;


Javascript




// Seller.js
import React, { useState } from 'react';
import axios from 'axios';
 
const Seller = () => {
    const [formData, setFormData] = useState({
        name: '',
        description: '',
        price: '',
        category: '',
        imageUrl: '',
    });
 
    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            const response = await axios.post('http://localhost:5000/product',
                formData);
            console.log(response.data);
        } catch (error) {
            console.error('Error:', error);
        }
    }
 
    const handleChange = (e) => {
        setFormData({ ...formData, [e.target.name]: e.target.value });
    }
 
    return (
        <div>
            <h2>Become a Seller</h2>
            <form onSubmit={handleSubmit}>
                <input type="text" name="name"
                    placeholder="Product Name" onChange={handleChange} />
                <input type="text" name="description"
                    placeholder="Description" onChange={handleChange} />
                <input type="number" name="price"
                    placeholder="Price" onChange={handleChange} />
                <input type="text" name="category"
                    placeholder="Category" onChange={handleChange} />
                <input type="text" name="imageUrl"
                    placeholder="Image URL" onChange={handleChange} />
                <button type="submit">Add Product</button>
            </form>
        </div>
    );
}
 
export default Seller;


Javascript




// ProductList.js
import React, {
    useState,
    useEffect
} from 'react';
import axios from 'axios';
import './index.css'
 
 
const ProductList = () => {
    const [products, setProducts] = useState([]);
 
    useEffect(() => {
        fetchProducts();
    }, []);
 
    const fetchProducts = async () => {
        try {
            const response = await axios.get('http://localhost:5000/product');
            setProducts(response.data);
        } catch (error) {
            console.error('Error:', error);
        }
    }
 
    return (
        <div className="container">
            <h2>Products</h2>
            <div className="product-list">
                {products.map((product, index) => (
                    <div key={product._id} className="product">
                        <h3>{product.name}</h3>
                        <img src={product.imageUrl}
                            alt={product.name} className="product-image" />
                        <p className="product-description">
                            Description: {product.description}
                        </p>
                        <p className="product-price">
                            Price: ${product.price}
                        </p>
                        <p className="product-category">
                            Category: {product.category}
                        </p>
                        {/* Add a line break after every third product */}
                        {((index + 1) % 3 === 0) &&
                            (<hr key={index} className="break-line" />)}
                        <button>Add to cart</button>
                    </div>
                ))}
            </div>
        </div>
    );
}
 
export default ProductList;


Javascript




// Nav.js
import React from 'react';
import { Link } from 'react-router-dom';
 
const Nav = () => {
    return (
        <nav className="navbar">
            <h1 className="navbar-brand">
                Marketplace
            </h1>
            <ul className="nav-links">
                <li className="nav-item">
                    <Link to="/" className="nav-link">
                        Home
                    </Link>
                </li>
                <li className="nav-item">
                    <Link to="/seller" className="nav-link">
                        Become a Seller
                    </Link>
                </li>
            </ul>
        </nav>
    );
}
 
export default Nav;


Start the project using the given command.

npm start

Output:

  • Browser Output
gfg68

Output

  • Output of data saved in database:

gfg68

Database output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads