Job Zeepdf
Job Zeepdf
ON
JobZee
(JOB SEEKING APP)
Submitted
By
MONIKA KANOJIA
(2207220140051)
1
CANDIDATE’S DECLARATION
Signature of Guide:
2
CERTIFICATE
This is to certify that this report represents the original work done by
EXTERNAL EXAMINER
3
ACKNOWLEDGEMENT
Last but not the least, I would like to thank all those who had
project.
4
ABSTRACT
Introduction
In the rapidly evolving job market, the need for efficient and user-friendly job-
seeking platforms has become paramount. Traditional job search methods
are increasingly being replaced by digital solutions that offer convenience
and accessibility. This project aims to develop a comprehensive job-
seeking application designed to bridge the gap between job seekers and
employers by leveraging advanced technologies and user-centric design
principles.
Objectives
The primary objectives of the job-seeking app project are:
1. User-Friendly Interface: Providing an intuitive interface that is
accessible to users of all demographics.
2. Streamlining Job Search: Implementing robust search algorithms to
match job seekers with relevant job opportunities efficiently.
3. Ease of Use: To ensure the app is simple to use with minimal steps
required to achieve desired actions.
5
Methodology
The development process of the job-seeking app involved several key stages:
1. User Research: Conducting surveys and focus groups to understand the
needs and preferences of potential users. Analyzing existing job-seeking
platforms to identify gaps and opportunities for innovation.
2. Design and Prototyping: Creating wireframes and prototypes based on
user feedback and best practices in UI/UX design. Ensuring the app
is user-friendly, visually appealing, and functional across various
devices and screen sizes.
3. Development: Implementing the app using a combination of front-end
and back-end technologies. The front-end was developed using
HTML, CSS, JavaScript and React Native for cross-platform
compatibility, while the back-end was built using Node.js and MongoDB
to ensure scalability and performance.
4. Testing and Quality Assurance: Conducting usability testing with a
focus group to gather feedback on the app's functionality and design.
Performing unit tests and integration tests to ensure the app is free from
critical bugs.
6
Results and Impact
The job-seeking app has been tested with a small group of users,
receiving positive feedback for its simplicity and ease of use. Key outcomes
include:
1. User Adoption: Steady increase in user registrations and active usage
within the first two months of launch.
2. User Satisfaction: High satisfaction rates among both job seekers and
employers, indicating the app's ability to meet their needs effectively.
Future Work
Plans for future development include:
1. Additional Filters: Adding more job search filters such as industry,
salary range, and job type to improve search accuracy.
2. Enhanced Communication: Implementing more robust communication
tools, including in-app messaging and video interview capabilities.
3. Partnerships: Forming Partnerships with educational institutions and
career services to provide additional resources for users.
4. Continuous Improvement: Regularly updating the app based on user
feedback and new trends in the job market to ensure ongoing
relevance and utility.
7
TABLE OF CONTENTS
3. Project Modules 17
4. System Design 21
System Architecture
Core Features
Data Flow Diagram (DFD)
Entity- Relationship Diagram (ERD)
6. Feasibility Study 31
7. Technology Stack 32
Front-End Technologies
Back-End Technologies
8
8. Implementation 36
Back-End Source Code
Front-End Source Code
9. Screen Shorts 82
11. Conclusion 89
12. Bibliography 90
9
CHAPTER 1: INTRODUCTION
1.1 Background
In today’s fast-paced and digitally connected world, the job market
has increasingly moved online. Traditional methods of job searching, such
as newspaper classifieds and physical job fairs, are being replaced by
digital platforms that offer greater accessibility and convenience. However,
many existing job-seeking applications are often complex, cluttered with
excessive features, and difficult to navigate, especially for users with
limited technical skills. There is a growing need for a simple, user-friendly job-
seeking app that caters to the essential needs of job seekers and employers alike.
1.2 Purpose
1 The purpose of the designing the online job portal is to give the job seekers a
platform for
2 finding a right and a satisfactory job according to their qualification. It also
connects the job
3 seekers with the major agencies.
4 The purpose of the designing the online job portal is to give the job seekers a
platform for
5 finding a right and a satisfactory job according to their qualification. It also
connects the job
6 seekers with the major agencies.
7 The purpose of the designing the online job portal is to give the job seekers a
platform for
1
8 finding a right and a satisfactory job according to their qualification. It also
connects the job
9 seekers with the major agencies.
10 The purpose of the designing the online job portal is to give the job seekers a
platform for
11 finding a right and a satisfactory job according to their qualification. It also
connects the job
12 seekers with the major agencies.
The purpose of the designing the online job portal is to give the job seekers a
platform for finding a right and a satisfactory job according to their
qualification. It also connects the job seekers with the major agencies.
It also provides Jobs portal for Job Seekers to submit their CV and apply for job
posting and Employer can select best Employees from Available CV based
on their payment option selection. This is basically a Job portal where
job seeker applies for jobs and employee post jobs and select appropriate
applicant.
Job portal is prepared to provide all categories of job and help to get
various type of job. The main purpose of job portal is to provide the
facility to job seekers for getting the quick job. So, it enables applicants to
search for jobs in a convenient manner and to enable employers to find suitable
candidates.
1
1.3 Objective
The Online Job Portal System is a package to be used by agencies to improve the
efficiency of business. The Online Job Portal System to be developed
benefits greatly the members. The system provides jobs catalogue and
information to members and helps them decide on the jobs to apply.
The Admin and employers can keep the jobs catalogue updated all the time so
that the Job seekers get the updated information all the time.
The online Job Portal System that is to be developed provides the members with
jobs information, online applying for jobs and many other facilities. This system
provides service to the job applications to search for working opportunities. Job
Portal will allow job provider to establish one to one relationships between
candidates. This portal will primarily focus on the posting and management of
job vacancies.
This system is designed such that ultimately all vacancies will be posted online
and would offer employees the facilities to post their vacancies online. It helps to
review and manage the resulting applications effectively through the web.
Employer can also find the resume according to key skill in very less amount of
time.
1
1.4 Scope
As of Indian market, there is ample opportunities for the job portal sites, as
more and more number of educated and skilled young people are coming out
each and every year. Also, as the growth rate of India is zooming to be
at a healthy rate over 7%, so it is boom time for corporate also. So, more and
more number of lucrative careers will be available for the job seekers. So, it is
now the right period for the job portal sites to think out of the box, and to make
most of the opportunities available.
The Scope for the system can be as follow:
Maintain Job Seeker and Employer records.
Maintain uploaded resumes.
Provide customized job posting.
Maintain Job Posting details and generate various report.
1
CHAPTER 2: IMPORTANCE OF JOB SEEKING
SYSTEM
1
The app streamlines the recruitment process by allowing employers
to post jobs and review applications digitally, thus speeding up the
hiring process.
3. Access to Opportunities:
Job seekers, especially those in remote or underserved areas, often
struggle to access job opportunities.
The app provides a centralized platform where job seekers can find
listings from various employers, regardless of location.
1
Benefits for Employers
1. Efficient Recruitment:
Employers can post job openings quickly and reach a large pool of
candidates.
The app's application management system allows employers to
review resumes, shortlist candidates, and communicate with
potential hires efficiently.
2. Access to a Larger Talent Pool:
By using the app, employers gain access to a wider range of
candidates, including those who might not be reached through
traditional recruitment channels.
This diversity in the talent pool can lead to better hiring decisions
and innovations within the organization.
3. Cost Effective:
Digital recruitment through the app can be more cost-effective than
traditional methods, reducing the need for physical advertisements,
recruitment agencies, and lengthy processes.
The app can help employers fill positions faster, reducing the costs
associated with prolonged vacancies.
1
CHAPTER 3: PROJECT MODULES
1
Features:
Job Posting:
Provides a form for employers to create new job listings with fields
for job title, description, requirements, location, salary range,
and application deadline.
Job Management:
Allows employers to edit, update, and delete job listings.
Includes features for marking positions as filled or closed.
Features:
Advance Job Search:
Implements search functionality with filters for location,
industry, job type(full-time, part-time, contract), experience level,
and salary range.
Save Job Listings:
Allows users to save job listings for later reference.
1
Application Tracking:
Provides a dashboard for job seekers to track the status of
their applications in real-time (e.g., submitted, under review,
interview scheduled).
Allows employers to view and manage applications, including
reviewing resumes, shortlisting candidates, and
updating application status.
6. Admin Module
This module is for administrative tasks and overall system management.
Features:
User Management:
Allows admin users to manage all user accounts, including job
seekers and employers.
Content Moderation:
Enables admin to review and moderate job listings and user-
generated content to ensure compliance with platform policies.
1
System Settings:
Provides configuration options for system-wide settings, such as
notification preferences, security settings, and feature toggles.
2
CHAPTER 4 : SYSTEM DESIGN
The proposed system for the Simple Job Seeking App aims to revolutionize the
job search and recruitment process by providing an intuitive, efficient, and user-
friendly platform for both job seekers and employers. This section outlines the
key components and functionalities of the proposed system, emphasizing its
architecture, core features, user interface design, and implementation strategy.
SYSTEM ARCHITECTURE
The system architecture of the Simple Job Seeking App is designed to be
scalable, secure, and maintainable. It comprises the following layers:
1. Client Layer:
Mobile Application: Developed using React Native for cross-
platform compatibility on iOS and Android devices.
Web Application: A responsive web interface for users who prefer
accessing the platform through a browser.
2. Server Layer:
Backend API: Built using Node.js and Express to handle requests,
process business logic, and communicate with the database.
Authentication Service: Secure user authentication using JWT
(JSON Web Tokens) and Auth for social media logins.
2
3. Database Layer:
Database Management System: MongoDB for flexible and
scalable storage of user profiles, job listings, applications, and other
data.
4. Security Layer:
Data Encryption: Use of SSL/TLS for encrypting data transmitted
between the client and server.
Access Control: Role-based access control to ensure that users can
only access functionalities relevant to their roles (job
seeker, employer, admin).
CORE FEATURES
The proposed system includes a comprehensive set of features tailored to
1. User Management:
Registration and Login: Easy registration and login options
2
Data Flow Diagram (DFD)
A Data Flow Diagram (DFD) is a graphical representation of the flow of data
within a system. It is a structured analysis and design tool that illustrates
the processes that occur within a system and the data flows between them.
DFDs help in understanding how data moves through an information system,
which is useful for both system designers and stakeholders to get a clear
picture of the system's functionality and structure.
Level 0
request
Job Portal
Job Seeker Employer
response
Admin
2
Level 1
The Level 1 DFD breaks down the main system process into sub-
processes.
request
Login
User 1 Login
response
Job Seeker
Job Seeker info
Login
Job Seeker
Availability of Job
seeker
Search Search
Criteria Job Postings Employer
User 3
Search result Login info
Job
Job Seeker
Login
2
Level 2
Username Password
Verify Login
User login
Login status
1.1
Role Base
authentication Login
Publish Vacancies
Jobs Job
2.4
2
Search criteria Search Job Company
Vacancy Info Employer
Job Seeker
Results 3.1
Job Info
Job
EdEimt/Bploc
lo yker info
Job Seeker
Accept/ Block
Job Seeker
4.1
Role Base
authentication Login
Admin
2
Entity – Relationship Diagram (ER Diagram)
An ER diagram helps visualize the relationships between entities in a database
system. For a job-seeking app, the primary entities typically include Job Seekers,
Employers, Jobs, Applications, and Administrators.
2. Employer Collection
Document Fields:
EmployerID ( unique identifier)
CompanyName
ContactNumber
Email
Password
Address
2
3. Job Collection
Document Fields:
JobID (unique identifier)
EmployerID (reference to Employer document)
JobTitle
JobDescription
Requirements
Salary
Location
PostDate
4. Application Collection
Document Fields:
ApplicationID (unique identifier)
JobID ( reference to Job document)
SeekerID ( reference to Job Seeker document)
ApplicationDate
Status
5. Administrator Collection
Document Fields:
AdminID (unique identifier)
Name
Email
Password
2
ER Diagram
Password
Qualifica
tion
UserNam
Admin Job Seeker
e
vievwf
UserNa
me
Password
Id
view
C_id
Company Apply
for job
C_name
AddVacancy
C_Address
type
2
CHAPTER 5: SYSTEM REQUIRED
SPECIFICATION
SOFTWARE REQUIREMENT
- Language JavaScript
- Framework React.js
HARDWARE REQUIREMENT
3
CHAPTER 6: FEAIBILITY STUDY
Feasibility study includes considerations of all the possible ways to provide the
solution to the given problem. The proposed solution should satisfy all the user
requirements and should be flexible enough so that the future changes can
be easily done based on the future coming requirements.
3
CHAPTER 7: TECHNOLOGY STACK
Front-End Technologies
HTML 5
HTML5 is the latest iteration of the Hypertext Markup
Language, designed for structuring and presenting content on the web. It
introduces semantic elements like <header>, <footer>, and <article> for
clearer page structure. Additionally, HTML5 supports native embedding of
audio and video with <audio> and <video> elements, eliminating the need
for third- party plugins. New form input types and attributes
simplify form validation and enhance user experience.
CSS 3
3
CSS provides a wide range of selectors to target specific HTML elements
and apply styles accordingly. It supports a variety of properties that
control the appearance and positioning of elements.
React Native
React Native is an open-source framework developed by Facebook
that enables developers to build mobile applications using JavaScript
and React, allowing a single codebase to run on both iOS and
Android platforms. This approach significantly reduces development
time and effort by eliminating the need for separate codebases for each
platform.
React.js
React.js, or React, is a JavaScript library developed by Facebook for
building dynamic and interactive user interfaces (UIs). It
revolutionized web development by introducing a component-based
architecture, where UIs are broken down into reusable, self-contained
components. Each component manages its own state, enabling developers
to write modular and predictable code. React's virtual DOM (Document
Object Model) is a key feature that optimizes performance by
efficiently updating and rendering components, reducing the need for
direct manipulation of the actual DOM.
3
Back-End Technologies
Node.js
Node.js is an open-source, cross-platform runtime environment
that allows developers to run JavaScript code outside of a web
browser. Developed by Ryan Dahl in 2009, Node.js uses the V8 JavaScript
engine, the same engine used by Google Chrome, to execute code. This
enables JavaScript to be used for server-side scripting, allowing
for the development of scalable and high-performance network
applications. Node.js is designed to handle a large number of simultaneous
connections with high throughput, making it suitable for real-time
applications such as chat servers, online gaming, and collaborative tools.
Express.js
Express.js, commonly known as Express, is a minimalist and flexible web
application framework for Node.js, designed to simplify the development
of web and mobile applications. Created by TJ Holowaychuk
and maintained by the Node.js foundation, Express streamlines server-
side coding for Node.js applications, making it easier to build APIs and
web servers.
Express.js supports various template engines such as Pug, EJS, and
Handlebars, allowing for server-side rendering of dynamic content. It also
offers comprehensive error handling mechanisms, ensuring
applications remain stable and reliable. The framework's extensibility
is another key advantage, with a rich ecosystem of plugins and
extensions available to add additional functionality. Widely used
for building single-page applications, RESTful APIs, and full-stack web
applications, Express.js is favored for its simplicity, flexibility, and
efficiency in setting up web
3
servers, managing routing, and handling middleware in both small
and large-scale projects.
Database
MongoDB
MongoDB is a NoSQL database management system recognized for
its versatility, scalability, and performance. Unlike traditional
relational databases, it stores data in JSON-like documents
organized within collections, offering a more intuitive and adaptable data
model.
MongoDB excels in handling large volumes of data and
growing workloads due to its horizontal scalability, which enables data
distribution across multiple servers. Its in-memory processing ensures
high-speed read and write operations, making it suitable for real-time
applications and high-throughput workloads. MongoDB's query
language supports a variety of operators and functions, facilitating
complex data queries and manipulations.
This flexibility has made MongoDB a popular choice across various
domains, including content management systems, e-commerce platforms,
real-time analytics, mobile applications, and IoT solutions.
3
CHAPTER 8: IMPLEMENTATION
3
4. Job
5. Layout
6. Not Found
application.js import{catchAsyncErrors}from"../middlewares/catchAsyncError.j;
import ErrorHandler from "../middlewares/error.js";
import { Application } from "../models/applicationSchema.js";
import { Job } from "../models/jobSchema.js";
import cloudinary from "cloudinary";
3
const allowedFormats = ["image/png","image/jpeg",
"image/webp"];
if (!allowedFormats.includes(resume.mimetype)) {
return next(
new ErrorHandler("Invalid file type. Please upload a PNG
file.", 400)
);
}
const cloudinaryResponse = await cloudinary.uploader.upload(
resume.tempFilePath
);
if (!cloudinaryResponse || cloudinaryResponse.error) {
console.error( "Cloudinary
Error:",
cloudinaryResponse.error || "Unknown Cloudinary error"
);
return next(new ErrorHandler("Failed to upload Resume to
Cloudinary", 500));
}
const { name, email, coverLetter, phone, address, jobId } =
req.body;
const applicantID = {
user: req.user._id, role:
"Job Seeker",
};
if (!jobId) {
return next(new ErrorHandler("Job not found!", 404));
}
const jobDetails = await Job.findById(jobId);
if (!jobDetails) {
return next(new ErrorHandler("Job not found!", 404));
}
3
const employerID = {
user: jobDetails.postedBy, role:
"Employer",
};
if (
!name ||
!email ||
!coverLetter ||
!phone ||
!address ||
!applicantID ||
!employerID ||
!resume
) {
return next(new ErrorHandler("Please fill all fields.",
400));
}
const application = await Application.create({
name, email,
coverLetter,
phone, address,
applicantID,
employerID,
resume: {
public_id: cloudinaryResponse.public_id,
url: cloudinaryResponse.secure_url,
},
});
res.status(200).json({
success: true,
message: "Application Submitted!",
application,
3
});
});
4
res.status(200).json({ success:
true, applications,
});
}
);
jobController.js import{catchAsyncErrors}from"../middlewares/catchAsyncError.j;
import { Job } from "../models/jobSchema.js";
import ErrorHandler from "../middlewares/error.js";
4
export const getAllJobs = catchAsyncErrors(async (req, res, next) => {
const jobs = await Job.find({ expired: false });
res.status(200).json({
success: true, jobs,
});
});
export const postJob = catchAsyncErrors(async (req, res, next)
=> {
const { role } = req.user;
if (role === "Job Seeker") {
return next(
new ErrorHandler("Job Seeker not allowed to access this resource.",
400)
);
}
const { title,
description,
category,
country, city,
location,
fixedSalary,
salaryFrom,
salaryTo,
} = req.body;
4
if ((!salaryFrom || !salaryTo) && !fixedSalary) {
return next(
new ErrorHandler(
"Please either provide fixed salary or ranged salary.",
400
)
);
}
4
});
export const getMyJobs = catchAsyncErrors(async (req, res, next) => {
const { role } = req.user;
if (role === "Job Seeker") {
return next(
new ErrorHandler("Job Seeker not allowed to access this resource.",
400)
);
}
const myJobs = await Job.find({ postedBy: req.user._id });
res.status(200).json({ success:
true, myJobs,
});
});
export const updateJob = catchAsyncErrors(async (req, res, next) => {
const { role } = req.user;
if (role === "Job Seeker") {
return next(
new ErrorHandler("Job Seeker not allowed to access this resource.",
400)
);
}
const { id } = req.params;
let job = await Job.findById(id);
if (!job) {
return next(new ErrorHandler("OOPS! Job not found.",
404));
}
job = await Job.findByIdAndUpdate(id, req.body, {
new: true, runValidators:
true,
4
useFindAndModify: false,
});
res.status(200).json({
success: true,
message: "Job Updated!",
});
});
4
const job = await Job.findById(id);
if (!job) {
return next(new ErrorHandler("Job not found.", 404));
}
res.status(200).json({
success: true, job,
});
} catch (error) {
return next(new ErrorHandler(`Invalid ID / CastError`,
404));
}
});
userController.js import{catchAsyncErrors}from"../middlewares/catchAsyncError.j;
import { User } from "../models/userSchema.js";
import ErrorHandler from "../middlewares/error.js";
import { sendToken } from "../utils/jwtToken.js";
4
phone,
password,
role,
});
sendToken(user, 201, res, "User Registered!");
});
4
export const logout = catchAsyncErrors(async (req, res, next)
=> {
res
.status(201)
.cookie("token", "", {
httpOnly: true,
expires: new Date(Date.now()),
}).json({
success: true,
message: "Logged Out Successfully.",
});
});
export const getUser = catchAsyncErrors((req, res, next) => {
const user = req.user;
res.status(200).json({
success: true, user,
});
});
2. Database
It shows Mongoose schema definitions for defining MongoDB data models.
dbConnection.js
import mongoose from "mongoose";
4
.catch((err) => {
console.log(`Some Error occurred while connecting to database $
{err}`);
});
};
3. Middleware
It includes code snippets for custom middleware functions, such
as authentication, authorization, or request logging.
Auth.js
import { User } from "../models/userSchema.js";
import { catchAsyncErrors } from "./catchAsyncError.js";
import ErrorHandler from "./error.js";
import jwt from "jsonwebtoken";
catchAsyncError.js
export const catchAsyncErrors = (theFunction) => {
return (req, res, next) => { Promise.resolve(theFunction(req, res,
next)).catch(next);
4
};
};
Error.js
class ErrorHandler extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
5
success: false, message:
err.message,
});
};
4. Models
applicationSchema.js
import mongoose from "mongoose";
import validator from "validator";
5
required: true,
},
},
});
jobSchema.js
import mongoose from "mongoose";
5
city: {
type: String,
required:[true, "Please provide a city name."],
},
location: {
type: String,
required:[true, "Please provide location."],
minLength:[20, "Location must contian at least 20 characters!"],
},
fixedSalary: {
type: Number,
minLength:[4, "Salary must contain at least 4 digits"], maxLength:[9,
"Salary cannot exceed 9 digits"],
},
salaryFrom: {
type: Number,
minLength:[4, "Salary must contain at least 4 digits"], maxLength:[9,
"Salary cannot exceed 9 digits"],
},
salaryTo: {
type: Number,
minLength:[4, "Salary must contain at least 4 digits"], maxLength:[9,
"Salary cannot exceed 9 digits"],
},
expired: {
type: Boolean,
default: false,
},
jobPostedOn: { type: Date,
default: Date.now,
},
postedBy: {
5
type: mongoose.Schema.ObjectId, ref:
"User",
required: true,
},
});
userSchema.js
import mongoose from "mongoose"; import
validator from "validator"; import bcrypt from
"bcrypt";
import jwt from "jsonwebtoken";
const userSchema = new mongoose.Schema({
name: {
type: String,
required: [true, "Please enter your Name!"],
minLength: [3, "Name must contain at least 3 Characters!"], maxLength: [30,
"Name cannot exceed 30 Characters!"],
},
email: {
type: String,
required: [true, "Please enter your Email!"],
validate: [validator.isEmail, "Please provide a valid
Email!"],
},
phone: {
type: Number,
required: [true, "Please enter your Phone Number!"],
},
password: {
type: String,
required: [true, "Please provide a Password!"],
5
minLength: [8, "Password must contain at least 8 characters!"],
maxLength: [32, "Password cannot exceed 32 characters!"],
select: false,
},
role: {
type: String,
required: [true, "Please select a role"], enum: ["Job
Seeker", "Employer"],
},
createdAt: { type: Date,
default: Date.now,
},
});
5
expiresIn: process.env.JWT_EXPIRES,
});
};
5. Routes
applicationRouter.js
import express from "express";
import { employerGetAllApplications,
jobseekerDeleteApplication,
jobseekerGetAllApplications,
postApplication,
} from "../controllers/applicationController.js";
import { isAuthenticated } from "../middlewares/auth.js";
jobRoutes.js
import express from "express";
import
{ deleteJob,
getAllJobs,
getMyJobs,
5
getSingleJob,
postJob,
updateJob,
} from "../controllers/jobController.js";
import { isAuthenticated } from "../middlewares/auth.js";
userRoutes.js
import express from "express";
import { deleteJob,
getAllJobs,
getMyJobs,
getSingleJob,
postJob,
updateJob,
} from "../controllers/jobController.js";
import { isAuthenticated } from "../middlewares/auth.js";
5
router.put("/update/:id", isAuthenticated, updateJob); router.delete("/delete/:id",
isAuthenticated, deleteJob); router.get("/:id", isAuthenticated, getSingleJob);
6. Utils
jwtToken.js
export const sendToken = (user, statusCode, res, message) => {
const token = user.getJWTToken();
const options = {
expires: new Date(
Date.now() + process.env.COOKIE_EXPIRE * 24 * 60 * 60 *
1000
),
httpOnly: true, // Set httpOnly to true
};
res.status(statusCode).cookie("token", token, options).json({
success: true, user,
message,
token,
});
};
App.js
import express from "express";
import { dbConnection } from "./database/dbConnection.js";
import jobRouter from "./routes/jobRoutes.js";
import userRouter from "./routes/userRoutes.js";
import applicationRouter from "./routes/applicationRoutes.js";
import { config } from "dotenv";
import cors from "cors";
5
import { errorMiddleware } from "./middlewares/error.js";
import cookieParser from "cookie-parser";
import fileUpload from "express-fileupload";
app.use(
cors({
origin: [process.env.FRONTEND_URL], method:
["GET", "POST", "DELETE", "PUT"], credentials: true,
})
);
app.use(cookieParser()); app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
fileUpload({ useTempFiles:
true, tempFileDir: "/tmp/",
})
);
app.use("/api/v1/user", userRouter); app.use("/api/v1/job", jobRouter);
app.use("/api/v1/application", applicationRouter); dbConnection();
app.use(errorMiddleware);
export default app;
server.js
6
import app from "./app.js";
import cloudinary from "cloudinary";
cloudinary.v2.config({
cloud_name: process.env.CLOUDINARY_CLIENT_NAME,
api_key: process.env.CLOUDINARY_CLIENT_API, api_secret:
process.env.CLOUDINARY_CLIENT_SECRET,
});
app.listen(process.env.PORT, () => {
console.log(`Server running at port ${process.env.PORT}`);
});
6
Front-End Source Code
Index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial- scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
1. Application
Application.jsx
import axios from "axios";
import React, { useContext, useState } from "react";
import toast from "react-hot-toast";
import { useNavigate, useParams } from "react-router-dom";
import { Context } from "../../main";
const Application = () => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [coverLetter, setCoverLetter] = useState("");
const [phone, setPhone] = useState(""); const [address,
setAddress] = useState(""); const [resume, setResume] =
useState(null);
const { isAuthorized, user } = useContext(Context);
const navigateTo = useNavigate();
6
// Function to handle file input changes const
handleFileChange = (event) => {
const resume = event.target.files[0];
setResume(resume);
};
const { id } = useParams();
const handleApplication = async (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("name", name); formData.append("email",
email); formData.append("phone", phone);
formData.append("address", address);
formData.append("coverLetter", coverLetter);
formData.append("resume", resume);
formData.append("jobId", id);
try {
const { data } = await axios.post(
"http://localhost:4000/api/v1/application/post", formData,
{
withCredentials: true, headers:
{
"Content-Type": "multipart/form-data",
},
}
);
setName(""); setEmail("");
setCoverLetter("");
setPhone("");
setAddress("");
6
setResume("");
toast.success(data.message);
navigateTo("/job/getall");
} catch (error) {
toast.error(error.response.data.message);
}
};
if (!isAuthorized || (user && user.role === "Employer")) {
navigateTo("/");
}
return (
<section className="application">
<div className="container">
<h3>Application Form</h3>
<form onSubmit={handleApplication}>
<input type="text"
placeholder="Your Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input type="email"
placeholder="Your Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="number"
placeholder="Your Phone Number"
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
6
<input type="text" placeholder="Your
Address" value={address}
onChange={(e) => setAddress(e.target.value)}
/>
<textarea placeholder="CoverLetter..."
value={coverLetter}
onChange={(e) => setCoverLetter(e.target.value)}
/>
<div>
<label
style={{ textAlign: "start", display: "block", fontSize: "20px"
}}
>
Select Resume
</label>
<input type="file"
accept=".pdf, .jpg, .png"
onChange={handleFileChange}
style={{ width: "100%" }}
/>
</div>
<button type="submit">Send Application</button>
</form>
</div>
</section>
);
};
6
ResumeModal.jsx
import React from "react";
2. Authorization
Login.jsx
import React, { useContext, useState } from "react"; import {
MdOutlineMailOutline } from "react-icons/md"; import { RiLock2Fill }
from "react-icons/ri";
import { Link, Navigate } from "react-router-dom";
import { FaRegUser } from "react-icons/fa";
import axios from "axios";
import toast from "react-hot-toast";
import { Context } from "../../main";
6
const{ isAuthorized, setIsAuthorized } = useContext(Context);
6
</div>
<form>
<div className="inputTag">
<label>Login As</label>
<div>
<select value={role} onChange={(e) =>
setRole(e.target.value)}>
<option value="">Select Role</option>
<option value="Employer">Employer</option>
6
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<RiLock2Fill />
</div>
</div>
<button type="submit" onClick={handleLogin}> Login
</button>
<Link to={"/register"}>Register Now</Link>
</form>
</div>
<div className="banner">
<img src="/login.png" alt="login" />
</div>
</section>
</>
);
};
Register.jsx
import React, { useContext, useState } from "react";
import { FaRegUser } from "react-icons/fa";
import { MdOutlineMailOutline } from "react-icons/md";
import { RiLock2Fill } from "react-icons/ri"; import { FaPencilAlt
} from "react-icons/fa"; import { FaPhoneFlip } from
"react-icons/fa6"; import { Link, Navigate } from "react-router-
dom"; import axios from "axios";
import toast from "react-hot-toast";
import { Context } from "../../main";
6
const Register = () => {
const [email, setEmail] = useState(""); const [name,
setName] = useState(""); const [phone, setPhone] =
useState("");
const [password, setPassword] = useState("");
const [role, setRole] = useState("");
7
if(isAuthorized){
return <Navigate to={'/'}/>
}
return (
<>
<section className="authPage">
<div className="container">
<div className="header">
<img src="/JobZeelogo.png" alt="logo" />
<h3>Create a new account</h3>
</div>
<form>
<div className="inputTag">
<label>Register As</label>
<div>
<select value={role} onChange={(e) =>
setRole(e.target.value)}>
<option value="">Select Role</option>
<option value="Employer">Employer</option>
<option value="Job Seeker">Job
Seeker</option>
</select>
<FaRegUser />
</div>
</div>
<div className="inputTag">
<label>Name</label>
<div>
<input type="text"
placeholder="Zeeshan"
value={name}
onChange={(e) => setName(e.target.value)}
/>
7
<FaPencilAlt />
</div>
</div>
<div className="inputTag">
<label>Email Address</label>
<div>
<input type="email"
placeholder="[email protected]"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<MdOutlineMailOutline />
</div>
</div>
<div className="inputTag">
<label>Phone Number</label>
<div>
<input type="number"
placeholder="12345678"
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
<FaPhoneFlip />
</div>
</div>
<div className="inputTag">
<label>Password</label>
<div>
<input type="password"
placeholder="Your Password"
value={password}
7
onChange={(e) => setPassword(e.target.value)}
/>
<RiLock2Fill />
</div>
</div>
<button type="submit" onClick={handleRegister}> Register
</button>
<Link to={"/login"}>Login Now</Link>
</form>
</div>
<div className="banner">
<img src="/register.png" alt="login" />
</div>
</section>
</>
);
};
export default Register;
3. Home
Home.jsx
import React from "react";
import { useContext } from "react";
import { Context } from "../../main";
import { Navigate } from "react-router-dom"; import
HeroSection from "./HeroSection"; import HowItWorks
from "./HowItWorks";
import PopularCategories from "./PopularCategories";
import PopularCompanies from "./PopularCompanies";
7
if (!isAuthorized) {
return <Navigate to={"/login"} />;
}
return (
<>
<section className="homePage page">
<HeroSection />
<HowItWorks />
<PopularCategories />
<PopularCompanies />
</section>
</>
);
};
export default Home;
HowItWorks.jsx
import React from "react";
import { FaUserPlus } from "react-icons/fa"; import {
MdFindInPage } from "react-icons/md"; import { IoMdSend }
from "react-icons/io";
7
Lorem, ipsum dolor sit amet consectetur adipisicing
elit.
Consequuntur, culpa.
</p>
</div>
<div className="card">
<MdFindInPage />
<p>Find a Job/Post a Job</p>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing
elit.
Consequuntur, culpa.
</p>
</div>
<div className="card">
<IoMdSend />
<p>Apply For Job/Recruit Suitable Candidates</p>
<p>
Lorem, ipsum dolor sit amet consectetur adipisicing
elit.
Consequuntur, culpa.
</p>
</div>
</div>
</div>
</div>
</>
);
};
export default HowItWorks;
7
4. Job
JobDetails.jsx
import React, { useContext, useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { Context } from "../../main";
const JobDetails = () => {
const { id } = useParams();
const [job, setJob] = useState({});
const navigateTo = useNavigate();
if (!isAuthorized) {
navigateTo("/login");
}
return (
<section className="jobDetail page">
<div className="container">
<h3>Job Details</h3>
<div className="banner">
7
<p>
Title: <span> {job.title}</span>
</p>
<p>
Category: <span>{job.category}</span>
</p>
<p>
Country: <span>{job.country}</span>
</p>
<p>
City: <span>{job.city}</span>
</p>
<p>
Location: <span>{job.location}</span>
</p>
<p>
Description: <span>{job.description}</span>
</p>
<p>
Job Posted On: <span>{job.jobPostedOn}</span>
</p>
<p>
Salary:{" "}
{job.fixedSalary ? (
<span>{job.fixedSalary}</span>
) : (
<span>
{job.salaryFrom} - {job.salaryTo}
</span>
)}
</p>
{user && user.role === "Employer" ? (
<></>
) : (
7
<Link to={`/application/${job._id}`}>Apply
Now</Link>
)}
</div>
</div>
</section>
);
};
5. Layout
Footer.jsx
import React, { useContext } from "react"; import {
Context } from "../../main"; import { Link } from
"react-router-dom";
import { FaFacebookF, FaYoutube, FaLinkedin } from "react- icons/fa";
import { RiInstagramFill } from "react-icons/ri";
7
<FaYoutube />
</Link>
<Link to={"https://www.youtube.com/@CodeWithZeeshu"}
target="_blank">
<FaLinkedin />
</Link>
<Link to={"https://www.instagram.com/z_4_zeeshuuu/"}
target="_blank">
<RiInstagramFill />
</Link>
</div>
</footer>
);
};
export default Footer;
Navbar.jsx
import React, { useContext, useEffect, useState } from "react";
import { Context } from "../../main";
import { Link, useNavigate } from "react-router-dom";
import axios from "axios";
import toast from "react-hot-toast";
import { GiHamburgerMenu } from "react-icons/gi";
7
{
withCredentials: true,
}
);
toast.success(response.data.message);
setIsAuthorized(false); navigateTo("/login");
} catch (error) {
toast.error(error.response.data.message),
setIsAuthorized(true);
}
};
return (
<nav className={isAuthorized ? "navbarShow" :
"navbarHide"}>
<div className="container">
<div className="logo">
<img src="/JobZee-logos white.png" alt="logo" />
</div>
<ul className={!show ? "menu" : "show-menu menu"}>
<li>
<Link to={"/"} onClick={() => setShow(false)}> HOME
</Link>
</li>
<li>
<Link to={"/job/getall"} onClick={() =>
setShow(false)}>
ALL JOBS
</Link>
</li>
<li>
<Link to={"/applications/me"} onClick={() =>
setShow(false)}>
8
{user && user.role === "Employer"
? "APPLICANT'S APPLICATIONS"
: "MY APPLICATIONS"}
</Link>
</li>
{user && user.role === "Employer" ? (
<>
<li>
<Link to={"/job/post"} onClick={() =>
setShow(false)}>
POST NEW JOB
</Link>
</li>
<li>
<Link to={"/job/me"} onClick={() =>
setShow(false)}>
VIEW YOUR JOBS
</Link>
</li>
</>
) : (
<></>
)}
<button onClick={handleLogout}>LOGOUT</button>
</ul>
<div className="hamburger">
<GiHamburgerMenu onClick={() => setShow(!show)} />
</div>
</div>
</nav>
);
};
export default Navbar;
8
CHAPTER 9: SCREENSHOTS
Home Page
8
Login Page
Register Page
8
All Available Jobs
8
Application Form
My Applications
8
Posted Jobs
8
CHAPTER 10: METHODOLOGY FOR TESTING
Testing Methodology
To ensure the reliability, functionality, and performance of the job-seeking
application, a multi-layered testing approach was implemented. This
comprehensive strategy included unit testing, integration testing, end-to-end
testing, and manual testing.
Unit Testing
Unit tests were written to validate the functionality of individual
components and modules in both the frontend and backend. For the backend, unit
tests were created using Jest, a popular testing framework for JavaScript.
These tests focused on key functions such as user authentication, job posting
creation, and data validation. For instance, the registerUser function was
tested to ensure it correctly hashes passwords and stores user data in the
database. On the frontend, React Testing Library was used to test React
components. Tests were designed to verify that components render correctly
with given props, handle user interactions appropriately, and manage internal
state as expected.
Integration Testing
Integration tests were conducted to ensure that different modules and
services work together as intended. In the backend, integration tests
verified the interaction between the Express.js server and MongoDB
database. Tools like Supertest were utilized to simulate HTTP requests and
8
test API endpoints. These tests ensured that routes such as `/api/users/register`
and `/api/jobs/create`
8
correctly handle requests, interact with the database, and return appropriate
responses. For the frontend, integration tests ensured that components
interact correctly with each other and with Redux state. For example, tests were
written to ensure that the login form component dispatches the correct
actions and updates the state upon successful authentication.
End-to-End Testing
End-to-end (E2E) tests were performed to validate the entire application flow,
from the user interface to the backend. Cypress was the primary tool used for
E2E testing. These tests simulated real user interactions with the
application, such as registering a new account, logging in, searching for jobs, and
applying for positions. E2E tests verified that the application behaves as expected
under various user scenarios, ensuring a seamless user experience.
Manual Testing
In addition to automated tests, manual testing was conducted to complement the
automated testing efforts. This involved exploratory testing to identify edge
cases and usability issues that automated tests might miss. The testing
team performed various user scenarios, such as job searches, profile
updates, and application submissions, to ensure that the application meets
functional and non- functional requirements.
By combining automated and manual testing methodologies, the job-seeking
application was thoroughly tested to ensure high quality, reliability, and
user satisfaction. This comprehensive testing strategy contributed to
delivering a robust and user-friendly application.
8
CONCLUSION
9
BIBLIOGRAPHY
https://www.w3schools.com/nodejs/
https://www.geeksforgeeks.org/nodejs/
https://www.mongodb.com/resources/products/platfo
rm/mongodb-atlas-tutorial
https://expressjs.com/
https://www.w3schools.com/REACT/DEFAULT.ASP
www.youtube.com/