Ticket Raising Platform using MERN Stack
Last Updated :
13 Mar, 2024
The Ticket Raising Platform project is a web application that enables users to create, manage, and track tickets for various issues or tasks. Built using the MERN (MongoDB, ExpressJS, ReactJS, NodeJS) stack, this project provides a comprehensive solution for efficiently handling ticket requests and resolutions.
Preview Image of Final Output:

Prerequisites
Approach to Creating a Ticket Raising Platform using MERN:
- Creating new tickets with titles, descriptions, priorities, and status.
- Viewing a list of tickets with filtering options based on status and priority.
- Updating ticket details such as status and priority.
- Deleting tickets.
- Searching for tickets based on keywords in titles, descriptions, or creators.
Steps to Create the NodeJS App and Installing Module:
Step 1: Initialize a new NodeJS project using the following command:
npm init -y
Step 2: Install required dependencies using the following command:
npm install express mongoose cors
Step 3: Create models and routes for handling ticket data (CRUD operations) in the routes/ and models/ directories.
Project Structure(Backend):
The updated dependencies in package.json file of backend will look like:
"dependencies": {
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^8.1.0"
}
Example: Write the following code in backend files.
JavaScript
//index.js
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const ticketRoutes = require('./routes/ticketRoutes.js');
const app = express();
const PORT = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
mongoose.connect('mongodb://localhost:27017/ticketRaisingPlatform', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
app.use('/api', ticketRoutes);
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
JavaScript
// models/ticket.js
const mongoose = require('mongoose');
const ticketSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
status: {
type: String,
enum: ['Open', 'In Progress', 'Resolved'],
default: 'Open'
},
priority: {
type: String,
enum: ['Low', 'Medium', 'High'],
default: 'Medium'
},
createdBy: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
});
const Ticket = mongoose.model('Ticket', ticketSchema);
module.exports = Ticket;
JavaScript
// ticketRoutes.js
const express = require('express');
const router = express.Router();
const Ticket = require('../models/Ticket.js');
router.get('/tickets',
async (req, res) => {
try {
const tickets = await Ticket.find();
res.json(tickets);
} catch (error) {
res.status(500).json({
message: error.message
});
}
});
router.get('/tickets/:id',
getTicket, (req, res) => {
res.json(res.ticket);
});
router.post('/tickets', async (req, res) => {
const ticket = new Ticket({
title: req.body.title,
description: req.body.description,
createdBy: req.body.createdBy,
status: 'Open',
priority: req.body.priority || 'Low',
});
try {
const newTicket = await ticket.save();
res.status(201).json(newTicket);
} catch (error) {
res.status(400).json({
message: error.message
});
}
});
router.patch('/tickets/:id', getTicket,
async (req, res) => {
if (req.body.title != null) {
res.ticket.title = req.body.title;
}
if (req.body.description != null) {
res.ticket.description = req.body.description;
}
if (req.body.status != null) {
res.ticket.status = req.body.status;
}
if (req.body.priority != null) {
res.ticket.priority = req.body.priority;
}
try {
const updatedTicket = await res.ticket.save();
res.json(updatedTicket);
} catch (error) {
res.status(400).json({
message: error.message
});
}
});
router.delete('/tickets/:id',
getTicket, async (req, res) => {
try {
// Use deleteOne method here
await res.ticket.deleteOne();
res.json({ message: 'Ticket deleted' });
} catch (error) {
res.status(500).json({
message: error.message
});
}
});
async function getTicket(req, res, next) {
let ticket;
try {
ticket = await Ticket.findById(req.params.id);
if (ticket == null) {
return res.status(404).json({
message: 'Ticket not found'
});
}
} catch (error) {
return res.status(500).json({
message: error.message
});
}
res.ticket = ticket;
next();
}
module.exports = router;
Start your server using the following command.
node server.js
Steps to Create the Frontend App and Installing Module:
Step 1: Create a new React.js project and install the required dependencies:-
npx create-react-app ticket-raising-platform.
Step 2: Navigate to the root directory of your project using the following command.
cd ticket-raising-platform
Step 3: Install the required packages in your project using the following command.
npm install axios
Step 5: Add the following code to theApp.js to render the featrues of ticket creation, listing, and management in the src/ directory.
Project Structure(Frontend):

The updated dependencies in package.json file of frontend will look like:
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.3.2",
"react": "^18.2.0",
"react-bootstrap": "^2.10.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.2",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4"
}
Example: Below is an example of creating a ticket raising platform using MERN.
CSS
/* Add the following styles to frontend/src/App.css */
body {
font-family: 'Arial', sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
.App {
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1,
h2 {
color: #333;
}
form {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 10px;
color: #555;
}
input,
textarea,
select {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: #4caf50;
color: white;
padding: 10px 15px;
border: none;
margin: 2%;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background-color: #fff;
margin-bottom: 10px;
padding: 15px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
li strong {
color: #4caf50;
}
li small {
color: #888;
}
/* Add a hover effect on ticket items */
li:hover {
transform: scale(1.02);
transition: transform 0.3s ease-in-out;
}
/* Styles for filter and search */
form label {
font-weight: bold;
}
form select,
form input[type="text"] {
width: calc(100% - 22px);
}
form input[type="text"] {
padding: 8px;
}
/* Optional: Style the search bar with a magnifying glass icon */
label[for="search"]::before {
content: "\1F50D";
/* Unicode for magnifying glass icon */
font-size: 18px;
margin-right: 8px;
}
/* Update the existing NavBar.css file or create a new one */
.navbar {
background-color: #2c3e50;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.navbar-brand {
font-size: 24px;
font-weight: bold;
color: #ecf0f1;
text-decoration: none;
}
/* ... (existing styles) */
.card-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
border: #333 2px 2px 2px 2px solid;
}
.card {
margin: 3%;
padding: 2%;
width: 200px;
border-radius: 15px;
text-align: center;
}
.card-content {
text-align: center;
font-weight: bolder;
}
.navbar-links {
list-style: none;
display: flex;
gap: 20px;
margin: 0;
}
.navbar-link {
font-size: 18px;
color: #ecf0f1;
text-decoration: none;
transition: color 0.3s ease-in-out;
}
.navbar-link:hover {
color: #3498db;
}
JavaScript
// App.js
import React, { useState, useEffect } from 'react';
import './App.css';
function App() {
const [tickets, setTickets] = useState([]);
const [formData, setFormData] = useState({
title: '',
description: '',
createdBy: '',
search: '',
priority: 'Low',
});
const [filter, setFilter] = useState({
status: 'All',
priority: 'All',
});
const fetchTickets = async () => {
try {
const response = await
fetch('http://localhost:5000/api/tickets');
const data = await response.json();
setTickets(data);
} catch (error) {
console.error(
'Error fetching tickets:', error);
}
};
useEffect(() => {
fetchTickets();
}, []);
const handleInputChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
const handleFilterChange = (e) => {
setFilter({
...filter,
[e.target.name]: e.target.value
});
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await
fetch('http://localhost:5000/api/tickets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
});
const newTicket = await response.json();
setTickets([...tickets, newTicket]);
setFormData({
title: '',
description: '',
createdBy: '',
search: '',
priority: 'Low'
});
} catch (error) {
console.error('Error creating ticket:', error);
}
};
const handleSearch = async (query) => {
// Trim white spaces and convert to lowercase
const searchQuery = query.toLowerCase().trim();
if (searchQuery !== '') {
const searchedTickets = tickets.filter(
(ticket) =>
ticket.title.toLowerCase().includes(searchQuery) ||
ticket.description.toLowerCase().includes(searchQuery) ||
ticket.createdBy.toLowerCase().includes(searchQuery)
);
setTickets(searchedTickets);
} else {
// If search query is empty, revert to original list of tickets
fetchTickets(); // Refetch tickets from the server
}
};
const handleDelete = async (ticketId) => {
try {
await
fetch(`http://localhost:5000/api/tickets/${ticketId}`, {
method: 'DELETE',
});
setTickets(tickets.filter((ticket) => ticket._id !== ticketId));
} catch (error) {
console.error('Error deleting ticket:', error);
}
};
const handlePriorityChange = async (ticketId, newPriority) => {
try {
const response = await
fetch(`http://localhost:5000/api/tickets/${ticketId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ priority: newPriority }),
});
const updatedTicket = await response.json();
setTickets((prevTickets) =>
prevTickets.map((ticket) =>
ticket._id === ticketId ? {
...ticket,
priority: updatedTicket.priority
} : ticket
)
);
} catch (error) {
console.error('Error updating priority:', error);
}
};
const filteredTickets = tickets.filter((ticket) => {
const statusFilter =
filter.status === 'All' ?
true : ticket.status === filter.status;
const priorityFilter =
filter.priority === 'All' ?
true : ticket.priority === filter.priority;
return statusFilter && priorityFilter;
});
function getPriorityColor(priority) {
switch (priority) {
case 'Low':
return '#aafaae'; // Green
case 'Medium':
return '#fcee68'; // Yellow
case 'High':
return '#fc8181'; // Red
default:
return '#fff'; // White for no priority
}
}
return (
<div className="App">
<h1>Ticket Raising Platform</h1>
<form onSubmit={handleSubmit}>
<label>
Title:
<input
type="text"
name="title"
value={formData.title}
onChange={handleInputChange}
/>
</label>
<label>
Description:
<textarea
name="description"
value={formData.description}
onChange={handleInputChange}
/>
</label>
<label>
Created By:
<input
type="text"
name="createdBy"
value={formData.createdBy}
onChange={handleInputChange}
/>
</label>
<label>
Priority:
<select
name="priority"
value={formData.priority}
onChange={handleInputChange}
>
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</label>
<button type="submit">Submit</button>
</form>
<h2>FILTERS AND SEARCH</h2>
<label>
Status:
<select name="status"
value={filter.status}
onChange={handleFilterChange}>
<option value="All">All</option>
<option value="Open">Open</option>
<option value="In Progress">In Progress</option>
<option value="Resolved">Resolved</option>
</select>
</label>
<label>
Priority:
<select name="priority"
value={filter.priority}
onChange={handleFilterChange}>
<option value="All">All</option>
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</label>
<label>
Search:
<input
type="text"
name="search"
value={formData.search}
onChange={(e) => {
setFormData({
...formData,
search: e.target.value
}); // Update formData.search
// Invoke handleSearch with the input value
handleSearch(e.target.value);
}}
/>
</label>
<h2>Tickets</h2>
<div className="card-container">
{filteredTickets.map((ticket) => (
<div
key={ticket._id}
className="card"
style={{
backgroundColor: getPriorityColor(ticket.priority)
}}
>
<div className="card-content">
<strong>{ticket.title}</strong> <br />
{ticket.description}<br />
(Created by: {ticket.createdBy})
</div>
<br />
<div className="card-actions">
<span>Priority: {ticket.priority}</span>
<br />
<br />
<label>
Update Priority:
<br />
<br />
<select
value={ticket.priority}
onChange={(e) =>
handlePriorityChange(ticket._id,
e.target.value)
}
>
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</label>
<button
onClick={() => handleDelete(ticket._id)}>
Delete
</button>
</div>
</div>
))}
</div>
</div>
);
}
export default App;
Start your application using the following command.
npm start
Output: Open a web browser and visit http://localhost:3000 to access the Ticket Raising Platform.

Similar Reads
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
Podcast Platform with MERN Stack
In this article, we'll be utilizing the MERN Stack (MongoDB, Express.js, React, Node.js) to develop a comprehensive podcast platform. This project aims to provide a thorough understanding of full-stack development by focusing on backend infrastructure with Express.js and MongoDB for data storage. We
6 min read
Music Streaming Platform using MERN Stack
In this tutorial, we'll walk through the process of creating a music streaming platform using the MERN stack. This project will allow users to browse playlists, view songs within each playlist, search for specific songs, and play them. We'll cover the basics of setting up a MongoDB database, creatin
7 min read
Stock Portfolio Tracker using MERN Stack
Investing in the stock market can be both exciting and daunting. With so many stocks to keep track of and market fluctuations to monitor, managing your portfolio can quickly become overwhelming. But fear not! With the power of technology, we can simplify this process through the creation of a Stock
9 min read
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 l
7 min read
Restaurant Reservation System using MERN Stack
Restaurant reservation system that helps people book tables at restaurants they like. It's built using React, Node.js, Express, and the MERN stack, along with Sass for styling. Users can search for restaurants based on their preferences, see details like location, description, price range, and conta
15+ min read
Social Networking Platform with MERN Stack
Social networking platforms are an important part of our lives, connecting people from all over the world. Building such platforms requires a robust technology stack that can handle a large number of users and real-time interactions. This article will guide you through the process of building a soci
15+ min read
Twenty-one Game using MEAN Stack
Twenty-one Game is a popular card game played in casinos worldwide. In this article, we'll explore how to create a Twenty-one game also known as the BlackJack game using the MEAN stack (MongoDB, Express.js, Angular, and Node.js). By building a Twenty-one game, we'll see the various aspects of web de
8 min read
Task Manager App using MERN Stack
Task Manager is very crucial to manage your tasks. In this article, we are going to develop a task manager application using the MERN stack. This application helps users to manage their tasks efficiently, offering essential features like creating new tasks, editing existing ones, and deleting tasks
10 min read
Community Forum Page using MERN Stack
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 informati
8 min read