Event Management Web App using MERN
Last Updated :
30 Jul, 2024
In this guide, we'll walk through the step-by-step process of building a feature-rich Event Management Web App. We will make use of the MERN stack to build this project.
Preview of final output: Let us have a look at how the final output will look like.
Final Output of Event Management AppPrerequisite
Approach to create Event Management Application
- Define the structure of an event using Mongoose schemas in a model file (e.g., `Event.js`).
- Develop routes for handling Create, Read, Update, and Delete (CRUD) operations in a dedicated `eventRoutes.js` file.
- Set up a MongoDB database and establish a connection in your Express application.
- Create a server file (e.g., `server.js`) where Express is configured to listen on a specific port.
- Design and implement a form component (`EventForm.js`) for adding new events.
- Develop a component (`EventList.js`) to display a list of events fetched from the server.
- Create a detailed event display component (`EventItem.js`) with features like editing, toggling reminders, and deleting.
- Style your components for an engaging user interface. You can utilize CSS .
Steps to Setup Backend with Node.js and Express
Step 1: Creating express app:
npm init -y
Step 2: Installing the required packages
npm install express mongoose body-parser cors
Project Structure:
Backend Project StructureThe 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",
}
Example: Below is the code example of the backend.
JavaScript
// server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const eventRoutes = require('./routes/eventRoutes');
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware
app.use(cors());
app.use(bodyParser.json());
// Connect to MongoDB
mongoose.connect('mongodb://localhost:27017/event_management', {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => {
console.log('Connected to MongoDB')
});
// Routes
app.use('/api/events', eventRoutes);
// Start server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
JavaScript
// routes/eventRoutes.js
const express = require('express');
const router = express.Router();
const Event = require('../models/Event');
// Get all events
router.get('/', async (req, res) => {
try {
const events = await Event.find();
res.json(events);
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// Create a new event
router.post('/', async (req, res) => {
const event = new Event({
title: req.body.title,
date: req.body.date,
reminder: req.body.reminder || false,
});
try {
const newEvent = await event.save();
res.status(201).json(newEvent);
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// Delete an event
router.delete('/:id', async (req, res) => {
console.log('****** Deleting event ******');
try {
console.log('Delete route called');
// Use findByIdAndDelete instead of findByIdAndRemove
await Event.findByIdAndDelete(req.params.id);
console.log('Event deleted');
res.json({ message: 'Event deleted' });
} catch (error) {
console.error('Error deleting event:', error);
res.status(500).json({ message: error.message });
}
});
// Update an event by ID
router.put('/:id', async (req, res) => {
const eventId = req.params.id;
const { title, date, reminder } = req.body;
console.log('reminder', reminder);
try {
// Find the event by ID in the database
const event = await Event.findById(eventId);
if (!event) {
return res.status(404).json({ message: 'Event not found' });
}
// Update the event properties
event.date = date;
event.title = title;
event.reminder = reminder;
console.log('event updated', event.reminder);
// Save the updated event
await event.save();
// You can send the updated event in the response if needed
res.json(event);
} catch (error) {
console.error('Error updating event:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
module.exports = router;
JavaScript
// models/Event.js
const mongoose = require('mongoose');
const eventSchema = new mongoose.Schema({
title: { type: String, required: true },
date: { type: Date, required: true },
reminder: { type: Boolean, default: false },
});
const Event = mongoose.model('Event', eventSchema);
module.exports = Event;
Steps to run the backend:
node server.js
Steps to Setup Frontend with React
Step 1: Create React App:
npx create-react-app event-management-frontend
Step 2: Switch to the project directory:
cd event-management-frontend
Step 3: Installing the required packages:
npm install axios
Project Structure:
Frontend Project StructureThe 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 code example of the frontend.
CSS
/* src/EventList.css */
.event-list {
display: flex;
flex-wrap: wrap;
}
.event-card {
background-color: #D2E3C8;
border: 1px solid #ddd;
border-radius: 8px;
margin: 10px;
padding: 15px;
width: 200px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.event-card:hover {
box-shadow: 0 4px 8px green;
}
.event-info {
margin-bottom: 10px;
}
.event-title {
font-weight: bold;
}
.event-date {
color: #555;
}
.event-actions {
display: flex;
justify-content: space-between;
}
.delete-btn:hover {
background-color: red;
color: white;
}
.rem-para {
background-color: green;
color: white;
padding: 2px;
width: fit-content;
position: relative;
left: -1px;
bottom: 22px;
}
.gfg {
padding: 15px;
color: white;
background-color: rgb(6, 162, 6);
border-radius: 25px;
}
/* form
*/
input {
padding: 5px;
width: 500px;
}
form {
display: flex;
flex-direction: column;
justify-content: center;
border: 2px solid red;
padding: 20px;
border-radius: 10px;
gap: 5px;
background: linear-gradient(to right, #FFA500, #FF6347);
;
}
.main-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
label {
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
font-weight: 500;
}
JavaScript
// src/App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import EventForm from './components/EventForm';
import EventList from './components/EventList';
import './App.css'
const App = () => {
const [events, setEvents] = useState([]);
useEffect(() => {
// Fetch events from the server
axios.get('http://localhost:5000/api/events')
.then(response => setEvents(response.data))
.catch(error => console.error(error));
}, []);
const handleEventAdd = (newEvent) => {
setEvents([...events, newEvent]);
};
const handleEventDelete = (id) => {
console.log("delete event " + id)
// Delete an event
axios.delete(`http://localhost:5000/api/events/${id}`)
.then(
() =>
setEvents(events.filter(event => event._id !== id)))
.catch(error => console.error(error));
};
const handleToggleReminder = (eventId) => {
// console.log('HI');
// Find the event by ID
const selectedEvent =
events.find(event => event._id === eventId);
// Toggle the reminder status
const updatedEvent =
{
...selectedEvent,
reminder: !selectedEvent.reminder
};
// console.log('Updated',updatedEvent);
// Update the event in the database
axios.put(`http://localhost:5000/api/events/${eventId}`, updatedEvent)
.then(response => {
// console.log('res',response.data);
// If the update is successful, update the events in the state
const updatedEvents = events.map(event =>
event._id === eventId ? updatedEvent : event
);
setEvents(updatedEvents);
})
.catch(
error =>
console.error(`Error updating reminder status for
event with ID ${eventId}:`, error));
};
const onEventEdit = (eventId, updatedData) => {
// Update the event in the database
axios.put(`http://localhost:5000/api/events/${eventId}`, updatedData)
.then(response => {
// If the update is successful, update the events in the state
const updatedEvents = events.map(event =>
event._id ===
eventId ?
{ ...event, ...updatedData } : event
);
setEvents(updatedEvents);
})
.catch(
error =>
console.error(`Error updating event with
ID ${eventId}:`, error)
);
};
return (
<div className='main-container'>
<h1 className='gfg'>
GFG
</h1>
<h2>Event Management App</h2>
<EventForm onEventAdd={handleEventAdd} />
<EventList
events={events}
onEventDelete={handleEventDelete}
onToggleReminder={handleToggleReminder}
onEventEdit={onEventEdit}
/>
</div>
);
};
export default App;
JavaScript
// src/EventList.js
import React, { useState } from 'react';
// Import the new EventItem component
import EventItem from './EventItem';
const EventList = (
{ events, onEventDelete,
onToggleReminder, onEventEdit
}
) => {
const [editedEvents, setEditedEvents] = useState([]);
const handleEventEdit = (eventId, updatedData) => {
// Find the index of the event being edited
const eventIndex =
editedEvents
.findIndex(
event =>
event._id === eventId
);
if (eventIndex !== -1) {
// Update the edited event in the local state
const updatedEditedEvents = [...editedEvents];
updatedEditedEvents[eventIndex] = {
...updatedEditedEvents[eventIndex],
...updatedData,
};
setEditedEvents(updatedEditedEvents);
} else {
// If the event is not already in the local state, add it
setEditedEvents(
[...editedEvents,
{ _id: eventId, ...updatedData }
]
);
}
// Pass the edit request to the parent component
onEventEdit(eventId, updatedData);
};
return (
<div className="event-list">
{events.map(event => (
<EventItem
key={event._id}
event={
editedEvents
.find(
editedEvent =>
editedEvent._id === event._id) || event
}
onToggleReminder={onToggleReminder}
onEventDelete={onEventDelete}
onEventEdit={handleEventEdit}
/>
))}
</div>
);
};
export default EventList;
JavaScript
// src/EventItem.js
import React, { useEffect, useState } from 'react';
import moment from 'moment';
const EventItem = (
{ event, onEventDelete,
onToggleReminder, onEventEdit
}) => {
const [isEditing, setIsEditing] = useState(false);
const [editedTitle, setEditedTitle] = useState(event.title);
const [editedDate, setEditedDate] =
useState(moment(event.date).format("YYYY-MM-DD"));
const [rem, setRem] = useState("")
useEffect(() => {
if (event) {
setRem(event.reminder ? "" : "Reminder On");
// Check if the event is today and has a reminder
const today = new Date();
const eventDate = new Date(event.date);
today.setHours(0, 0, 0, 0);
eventDate.setHours(0, 0, 0, 0);
if (today.getTime() ===
eventDate.getTime() &&
event.reminder) {
alert(`Today is the day of the event:
${event.title}`);
}
} else {
setRem("Reminder On");
}
}, [event, event.reminder]);
const handleEditClick = () => {
setIsEditing(true);
};
const handleSaveClick = () => {
// Perform the update in the database (you may use an API request here)
onEventEdit(event._id,
{
title: editedTitle,
date: editedDate
});
// Exit the edit mode
setIsEditing(false);
};
const handleCancelClick = () => {
// Reset the edited values and exit the edit mode
setEditedTitle(event.title);
setEditedDate(moment(event.date)
.format("YYYY-MM-DD"));
setIsEditing(false);
};
return (
<div className="event-card">
<p className='rem-para'>
{
event.reminder ? "Reminder On" : ""
}
</p>
<div className="event-info">
{isEditing ? (
<>
<input
type="text"
value={editedTitle}
onChange={
(e) =>
setEditedTitle(e.target.value)
}
/>
<input
type="date"
value={editedDate}
onChange={
(e) =>
setEditedDate(e.target.value)
}
/>
</>
) : (
<>
<h3 className="event-title">{event.title}</h3>
<hr />
<span className="event-date">
<span style={{ "fontWeight": "700" }}>
Event On:
</span>
{
moment(event.date)
.add(1, 'days').calendar()
};
</span>
</>
)}
</div>
<div className="event-actions">
{isEditing ? (
<>
<button onClick={handleSaveClick}>
Save
</button>
<button onClick={handleCancelClick}>
Cancel
</button>
</>
) : (
<>
<button onClick={
() => onToggleReminder(event._id)
}>
{
event.reminder ?
'Disable Reminder' : 'Enable Reminder'
}
</button>
<button className='delete-btn'
onClick={
() => onEventDelete(event._id)}>
Delete
</button>
<button onClick={handleEditClick}>
Edit
</button>
</>
)}
</div>
</div>
);
};
export default EventItem;
JavaScript
// src/EventForm.js
import React, { useState } from 'react';
import axios from 'axios';
import './EventForm.css';
const EventForm = ({ onEventAdd }) => {
const [newEvent, setNewEvent] =
useState({ title: '', date: '', reminder: false });
const handleInputChange = (e) => {
setNewEvent(
{
...newEvent,
[e.target.name]: e.target.value
}
);
};
const handleSubmit = (e) => {
e.preventDefault();
// Create a new event
axios.post('http://localhost:5000/api/events', newEvent)
.then(response => {
onEventAdd(response.data);
setNewEvent({ title: '', date: '', reminder: false });
})
.catch(error => console.error(error));
};
return (
<form onSubmit={handleSubmit}>
<label>Title:</label>
<input type="text" name="title"
value={newEvent.title}
onChange={handleInputChange} required />
<label>Date:</label>
<input type="date"
name="date" value={newEvent.date}
onChange={handleInputChange} required />
<button type="submit">Add Event</button>
</form>
);
};
export default EventForm;
Steps to run the app:
npm start
Output:
Similar Reads
35+ MERN Stack Projects with Source Code [2024]
The MERN stack, comprising MongoDB, Express JS, React, and Node JS, is a powerful combination that enables developers to build full-stack web applications using JavaScript. MongoDB serves as the database, Express.js handles server-side logic, React manages the client-side interface, and Node.js faci
6 min read
Stock Market Portfolio App using MERN Stack
The Stock Market Portfolio project is a web application that helps to efficiently manage and track stock market investments and portfolios. In this article, we will see a step-wise process of building a Stock Market Portfolio using the power of the MERN stack. Project Preview: Let us have a look at
5 min read
Hospital Management Application using MERN Stack
In the fast-paced world of healthcare, it's vital to manage hospital tasks effectively to ensure top-notch patient care. This article explores creating a strong Hospital Management App using the MERN stack â that's MongoDB, Express, React, and Node.js, breaking down the process for easier understand
15+ min read
Social Media Platform using MERN Stack
In web development, creating a "Social Media Website" will showcase and utilising the power of MERN stack â MongoDB, Express, React, and Node. This application will provide users the functionality to add a post, like the post and able to comment on it.Preview Image: Let us have a look at how the fin
7 min read
Bookstore Ecommerce App using MERN Stack
Bookstore E-commerce project is a great way to showcase your understanding of full-stack development. In this article, we'll walk through the step-by-step process of creating a Bookstore E-commerce using the MERN (MongoDB, Express.js, React, Node.js) stack. This project will showcase how to set up a
8 min read
Chat Website using MERN Stack
The "Chat Website" project is a dynamic web application that is used for real-time communication. The MERN stack, comprised of MongoDB, Express.js, React.js, and Node.js, is a powerful combination of technologies for developing robust and scalable web applications. In this article, we'll explore the
4 min read
Restaurant App using MERN Stack
Creating a Restaurant app will cover a lot of features of the MERN stack. In this tutorial, we'll guide you through the process of creating a restaurant application using the MERN stack. The application will allow users to browse through a list of restaurants, view their menus, and add items to a sh
11 min read
Real Estate Management using MERN
In this article, we will guide you through the process of building a Real Estate Management Application using the MERN stack. MERN stands for MongoDB, Express, React, and Node. MongoDB will serve as our database, Express will handle the backend, React will create the frontend, and Node.js will be th
9 min read
Fruit and Vegetable Market Shop using MERN
In this comprehensive guide, we'll walk through the step-by-step process of creating a Fruit and Vegetable Market Shop using the MERN (MongoDB, Express.js, React, Node.js) stack. This project will showcase how to set up a full-stack web application where users can view, filter, and purchase various
8 min read
Event Management Web App using MERN
In this guide, we'll walk through the step-by-step process of building a feature-rich Event Management Web App. We will make use of the MERN stack to build this project.Preview of final output: Let us have a look at how the final output will look like.Final Output of Event Management AppPrerequisite
9 min read