In the ever-expanding digital landscape, fostering meaningful connections within communities is paramount. The Community Forum Page project, developed using the MERN (MongoDB, Express, React, Node) stack, aims to provide a dynamic platform for users to engage in discussions, share valuable information, and cultivate a thriving community environment.
Preview of final output: Let us have a look at how the final output will look like.

Prerequisites:
Approach to create Community Forum Page:
- Creating BackEnd for our Application
- Creating FrontEnd for Application
- Connecting It with MongoDB
Steps to Create the Backend:
Step 1: Create a directory for project
npm init backendStep 2: Open project using the command
cd backendStep 3: Installing the required packages
npm install express mongoose cors body-parserProject Structure:

The updated dependencies in package.json file for backend will look like:
"dependencies": {
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^8.0.0",
}
Explanation:
- Imports: Express, Mongoose, body-parser, cors modules for web server, MongoDB connection, request body handling, and CORS.
- Creates an Express app instance, specifies a port (from PORT environment variable or defaulting to 5000).
- Middleware setup: Handles CORS and parses JSON request bodies using cors and body-parser.
- Defines "Request" data structure with attributes like residentName, content, and likes using Mongoose.
- API Endpoints: Create, Read, Update (like), and Delete operations for requests are defined.
- Server start: The server starts, listens on the specified port, and logs an operational message once running.
Example: Create server.js (Express Server) as connection between frontEnd and BackEnd. Insert the following code to it :
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const PORT = process.env.PORT || 5000;
app.use(cors());
app.use(bodyParser.json());
mongoose.connect(
'mongodb://localhost:27017/societyDB',
{
useNewUrlParser: true,
useUnifiedTopology: true
});
const requestSchema = new mongoose.Schema({
residentName: { type: String, required: true },
content: { type: String, required: true },
likes: { type: Number, default: 0 },
});
const Request =
mongoose.model('Request', requestSchema);
// Create a new request
app.post('/requests', async (req, res) => {
try {
const { residentName, content } = req.body;
const newRequest =
new Request({ residentName, content });
const savedRequest = await newRequest.save();
res.json(savedRequest);
} catch (error) {
res.status(500)
.json({ error: 'Internal Server Error' });
}
});
// Get all requests
app.get('/requests', async (req, res) => {
try {
const requests = await Request.find();
res.json(requests);
} catch (error) {
res.status(500)
.json(
{
error: 'Internal Server Error'
}
);
}
});
// Like a request
app.patch('/requests/:id/like', async (req, res) => {
try {
const { id } = req.params;
const updatedRequest =
await Request.findByIdAndUpdate(
id,
{ $inc: { likes: 1 } },
{ new: true });
res.json(updatedRequest);
} catch (error) {
res.status(500)
.json(
{
error: 'Internal Server Error'
}
);
}
});
// Delete a request
app.delete('/requests/:id', async (req, res) => {
try {
const { id } = req.params;
await Request.findByIdAndDelete(id);
res.json(
{
message: 'Request deleted successfully'
}
);
} catch (error) {
res.status(500)
.json(
{
error: 'Internal Server Error'
}
);
}
});
// Example: routes/requests.js
const router = express.Router();
app.listen(PORT,
() =>
console.log(
`Server is running on port ${PORT}`
)
);
Steps to Create the Frontend:
Step 1: Set up React frontend using the command.
npx create-react-app clientStep 2: Navigate to the project folder using the command.
cd clientStep 3: Installing the required packages:
npm i axios react-router-domProject Structure:

The updated dependencies in package.json for frontend will look like:
"dependencies": {
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}
Explanation:
- Form component with a title (FormTitle) indicating it's for creating requests.
- Utilizes flexbox with a column direction and small gaps for a clean layout.
- Includes two form fields: Resident Name (text input) and Request Content (textarea), both styled.
- Utilizes the useState hook to manage state for residentName and content.
- handleSubmit function prevents default form submission, creates a new request object, calls onAddRequest callback with the new request, and clears form fields.
- Receives onAddRequest prop as a callback function for handling new request additions.
- Uses axios for asynchronous GET request to http://localhost:5000/requests, storing data in the requests state.
- handleLike function makes a PATCH request to update likes for a specific request, then refreshes the request list.
- UI divided into two columns: left column has RequestForm for new requests, and right column displays a list of community requests.
- Community requests show resident name, issue content, and a "Like" button for user interaction.
/* src/components/RequestForm.css */
.request-form-container {
width: 600px;
padding: 100px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
margin: 2%;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
input,
textarea {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.submit-button {
background-color: #4caf50;
color: #fff;
padding: 10px;
border: none;
border-radius: 4px;
cursor: pointer;
}
/* src/components/RequestList.css */
.request-list-container {
padding: 20px;
display: flex;
flex-direction: row;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.request-list {
display: flex;
flex-wrap: wrap;
flex-direction: row;
margin: 2%;
}
.request-item {
margin: 1%;
padding: 10px;
width: 400px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
}
.resident-name {
font-weight: bold;
margin-bottom: 5px;
}
.request-content {
margin-bottom: 10px;
}
.likes {
color: #888;
}
.like-button {
background-color: #4caf50;
color: #fff;
padding: 5px 10px;
border: none;
border-radius: 4px;
cursor: pointer;
}
// src/App.js
import React from "react";
import {
BrowserRouter as Router,
Route, Routes
} from "react-router-dom";
import RequestList
from "./components/RequestList";
import RequestForm
from "./components/RequestForm";
import About from "./components/About";
import Navbar from "./components/Navbar";
const App = () => {
return (
<Router>
<Navbar />
<Routes>
<Route path="/"
element={<RequestList />} />
<Route path="/about"
element={<About />} />
</Routes>
</Router>
);
};
export default App;
// src/components/RequestList.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
// Import the RequestForm component
import RequestForm from './RequestForm';
import './RequestList.css';
const RequestList = () => {
const [requests, setRequests] = useState([]);
const fetchRequests = async () => {
try {
const response =
await axios.get('http://localhost:5000/requests');
setRequests(response.data);
} catch (error) {
console.error('Error fetching requests:', error);
}
};
useEffect(() => {
fetchRequests();
}, []);
const handleLike = async (id) => {
try {
await
axios.patch(`
http://localhost:5000/requests/${id}/like
`);
// Refresh the list of requests after liking
fetchRequests();
} catch (error) {
console.error('Error liking request:', error);
}
};
return (
<div className="request-list-container">
<RequestForm onAddRequest={
(newRequest) =>
setRequests([newRequest, ...requests])
} />
<ul className="request-list">
{requests.map((request) => (
<div key={request._id}
className="request-item">
<p className="resident-name">
{request.residentName}
</p>
<p className="request-content">
{request.content}
</p>
<p className="likes">
Likes: {request.likes}
</p>
<button className="like-button"
onClick=
{
() => handleLike(request._id)
}>
Like
</button>
</div>
))}
</ul>
</div>
);
};
export default RequestList;
// src/components/RequestForm.js
import React, { useState } from 'react';
import axios from 'axios';
import './RequestForm.css'; // Import the CSS file for styling
const RequestForm = ({ onAddRequest }) => {
const [residentName, setResidentName] = useState('');
const [content, setContent] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response =
await axios.post('http://localhost:5000/requests', {
residentName,
content,
});
// Assuming the backend returns the newly created request
onAddRequest(response.data);
setResidentName('');
setContent('');
} catch (error) {
console.error('Error creating request:', error);
}
};
return (
<div className="request-form-container">
<h2>Create a Request</h2>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="residentName">
Resident Name:
</label>
<input
id="residentName"
type="text"
value={residentName}
onChange={
(e) =>
setResidentName(e.target.value)
}
/>
</div>
<div className="form-group">
<label htmlFor="content">
Content:
</label>
<textarea
id="content"
value={content}
onChange={
(e) =>
setContent(e.target.value)
}
/>
</div>
<button type="submit"
className="submit-button">
Submit Request
</button>
</form>
</div>
);
};
export default RequestForm;
// src/components/About.js
import React from 'react';
import styled from 'styled-components';
const AboutContainer = styled.div`
max-width: 800px;
margin: 20px auto;
padding: 20px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 8px;
`;
const Title = styled.h2`
color: #333;
margin-bottom: 20px;
`;
const Paragraph = styled.p`
line-height: 1.6;
margin-bottom: 10px;
`;
const About = () => {
return (
<AboutContainer>
<Title>About Community Forum</Title>
<Paragraph>
Welcome to the Community Forum, a place where
residents can connect, share ideas, and support
each other. This platform allows you to raise
requests, express your opinions, and engage in
discussions with fellow community members.
</Paragraph>
<Paragraph>
We believe in fostering a sense of community
and collaboration. Feel free to explore the
forum, like and contribute to requests, and
be an active participant in shaping our community.
</Paragraph>
{/* Add more information as needed */}
</AboutContainer>
);
};
export default About;
// src/components/Navbar.js
import React from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
const NavbarContainer = styled.div`
background-color: #212e3d;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
`;
const Logo = styled.h1`
color: #fff;
margin: 0;
`;
const NavLink = styled(Link)`
color: #fff;
text-decoration: none;
margin-left: 20px;
font-weight: bold;
transition: color 0.3s ease-in-out;
&:hover {
color: #0e87ea;
}
`;
const Navbar = () => {
return (
<NavbarContainer>
<Logo>Community Forum</Logo>
<div>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">About</NavLink>
{/* Add more navigation links as needed */}
</div>
</NavbarContainer>
);
};
export default Navbar;
Steps to run the Application:
node server.js and npm startOutput:
Output of Data Saved in Database:
