Community Marketplace App using MERN Stack
Last Updated :
07 Mar, 2024
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.
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:
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
const express = require( 'express' );
const mongoose = require( 'mongoose' );
const cors = require( 'cors' );
const app = express();
const PORT = process.env.PORT || 5000;
useNewUrlParser: true ,
useUnifiedTopology: true
})
.then(() => console.log( 'Connected to MongoDB' ))
. catch (err => console.error(err));
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
description: String,
price: {
type: Number,
required: true
},
category: String,
imageUrl: String,
});
const Product = mongoose.model( 'Product' , productSchema);
app.use(cors());
app.use(express.json());
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' });
}
});
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' });
}
});
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:
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
body {
font-family : Arial , sans-serif ;
margin : 0 ;
padding : 0 ;
}
.container {
max-width : 800px ;
margin : 20px auto ;
padding : 0 20px ;
}
h 2 {
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-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
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
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 {
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
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 {
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>
{ }
{((index + 1) % 3 === 0) &&
(<hr key={index} className= "break-line" />)}
<button>Add to cart</button>
</div>
))}
</div>
</div>
);
}
export default ProductList;
|
Javascript
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:
Output
- Output of data saved in database:
Database output
Share your thoughts in the comments
Please Login to comment...