├── backend
├── .gitignore
├── public
│ ├── cv
│ │ ├── pal@a.com.pdf
│ │ └── test1@a.com.pdf
│ └── image
│ │ ├── pal@a.com.jpg
│ │ ├── test1@a.com.jpg
│ │ ├── undefined.jpeg
│ │ ├── undefined.jpg
│ │ └── test1@a.com.jpeg
├── routes
│ ├── testAPI.js
│ ├── Recruiters.js
│ ├── Users.js
│ ├── Applicant.js
│ ├── application.js
│ └── Jobs.js
├── models
│ ├── Users.js
│ ├── recruiters.js
│ ├── applicants.js
│ ├── Jobs.js
│ └── applications.js
├── package.json
└── server.js
├── frontend
├── .gitignore
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── index.html
├── src
│ ├── components
│ │ ├── Common
│ │ │ ├── cool-background.png
│ │ │ ├── Home.js
│ │ │ ├── styles.css
│ │ │ ├── login.css
│ │ │ ├── my_applications.js
│ │ │ ├── Joblistings.js
│ │ │ ├── Login.js
│ │ │ ├── rate_my_employee.js
│ │ │ ├── Profileedit_recruiter.js
│ │ │ ├── Edit-job.js
│ │ │ ├── Add_jobs.js
│ │ │ ├── Job_info.js
│ │ │ ├── my_employees.js
│ │ │ ├── Profileedit_applicant.js
│ │ │ ├── job_application_info_rec.js
│ │ │ ├── Register.js
│ │ │ └── View_job_listings_applicant.js
│ │ ├── Users
│ │ │ ├── Profile.js
│ │ │ └── UsersList.js
│ │ └── templates
│ │ │ ├── Navbar.js
│ │ │ ├── Applicant_navbar.js
│ │ │ └── Recruiter_navbar.js
│ ├── setupTests.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── App.css
│ ├── logo.svg
│ ├── App.js
│ └── serviceWorker.js
├── package.json
└── README.md
├── Assignment 1.pdf
├── LICENSE
└── README.md
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/Assignment 1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/Assignment 1.pdf
--------------------------------------------------------------------------------
/frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/frontend/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/frontend/public/logo192.png
--------------------------------------------------------------------------------
/frontend/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/frontend/public/logo512.png
--------------------------------------------------------------------------------
/backend/public/cv/pal@a.com.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/cv/pal@a.com.pdf
--------------------------------------------------------------------------------
/backend/public/cv/test1@a.com.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/cv/test1@a.com.pdf
--------------------------------------------------------------------------------
/backend/public/image/pal@a.com.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/image/pal@a.com.jpg
--------------------------------------------------------------------------------
/backend/public/image/test1@a.com.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/image/test1@a.com.jpg
--------------------------------------------------------------------------------
/backend/public/image/undefined.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/image/undefined.jpeg
--------------------------------------------------------------------------------
/backend/public/image/undefined.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/image/undefined.jpg
--------------------------------------------------------------------------------
/backend/public/image/test1@a.com.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/backend/public/image/test1@a.com.jpeg
--------------------------------------------------------------------------------
/frontend/src/components/Common/cool-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/veeral-agarwal/job-portal/HEAD/frontend/src/components/Common/cool-background.png
--------------------------------------------------------------------------------
/frontend/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/frontend/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/backend/routes/testAPI.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 |
4 | // GET request
5 | // Just a test API to check if server is working properly or not
6 | router.get("/", function(req, res) {
7 | res.send("API is working properly !");
8 | });
9 |
10 | router.get("/hie", function(req, res) {
11 | res.send("hii ");
12 | });
13 |
14 | router.get("/hiiiiie", function(req, res) {
15 | res.send("hello");
16 | });
17 |
18 | module.exports = router;
19 |
--------------------------------------------------------------------------------
/frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/backend/models/Users.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const UserSchema = new Schema({
5 | name: {
6 | type: String,
7 | required: true
8 | },
9 | password: {
10 | type: String,
11 | required: true
12 | },
13 | type: {
14 | type: String,
15 | required: true
16 | },
17 | email: {
18 | type: String,
19 | required: true
20 | },
21 | date:{
22 | type: Date,
23 | required: false
24 | }
25 | });
26 |
27 | module.exports = User = mongoose.model("Users", UserSchema);
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "nodemon server.js"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "dependencies": {
14 | "body-parser": "^1.19.0",
15 | "cors": "^2.8.5",
16 | "express": "^4.17.1",
17 | "mongoose": "^5.11.11",
18 | "multer": "^1.4.2",
19 | "nodemon": "^2.0.7",
20 | "path": "^0.12.7"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/src/components/Common/Home.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 |
4 | export default class Home extends Component {
5 |
6 | constructor(props) {
7 | super(props);
8 | this.state = {
9 | name:'',
10 | email:''
11 | }
12 | }
13 |
14 | componentDidMount() {
15 | // this.name = "veeral";
16 | }
17 |
18 | render() {
19 | return (
20 |
21 | Happy Coding! {};
22 |
23 | )
24 | }
25 | }
--------------------------------------------------------------------------------
/frontend/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/backend/models/recruiters.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const recruiterSchema = new Schema({
5 | name: {
6 | type: String,
7 | required: true
8 | },
9 | password: {
10 | type: String,
11 | required: true
12 | },
13 | type: {
14 | type: String,
15 | required: true,
16 | default: "recruiter"
17 | },
18 | email: {
19 | type: String,
20 | required: true
21 | },
22 | contact_number: {
23 | type: Number,
24 | required: false
25 | },
26 | bio: {
27 | type: String,
28 | required: false
29 | },
30 | date:{
31 | type: Date,
32 | required: false
33 | },
34 |
35 | });
36 |
37 | module.exports = Recruiter = mongoose.model("recruiters", recruiterSchema);
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Veeral Agarwal
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/backend/models/applicants.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const applicantSchema = new Schema({
5 | name: {
6 | type: String,
7 | required: true
8 | },
9 | password: {
10 | type: String,
11 | required: true
12 | },
13 | type: {
14 | type: String,
15 | required: true,
16 | default: "applicant"
17 | },
18 | email: {
19 | type: String,
20 | required: true
21 | },
22 | education:{
23 | type:[],
24 | required: false
25 | },
26 | list_of_languages: {
27 | type: String,
28 | required: true
29 | },
30 | rating: {
31 | type: Number,
32 | required: true,
33 | default: 0,
34 | },
35 | date:{
36 | type: Date,
37 | required: false
38 | },
39 | image:{
40 | data:Buffer,
41 | required:false,
42 | type:String,
43 | },
44 | cv:{
45 | data:Buffer,
46 | type:String,
47 | required:false,
48 | },
49 | rate_count:{
50 | type:Number,
51 | required:false,
52 | default:0,
53 | },
54 | application_count:{
55 | type:Number,
56 | default:0,
57 | required:false,
58 | },
59 | });
60 |
61 | module.exports = Applicant = mongoose.model("applicants", applicantSchema);
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "template",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.11.2",
7 | "@material-ui/icons": "^4.11.2",
8 | "@material-ui/lab": "^4.0.0-alpha.57",
9 | "@testing-library/jest-dom": "^4.2.4",
10 | "@testing-library/react": "^9.3.2",
11 | "@testing-library/user-event": "^7.1.2",
12 | "axios": "^0.19.2",
13 | "bcryptjs": "^2.4.3",
14 | "bootstrap": "^4.5.3",
15 | "react": "^16.12.0",
16 | "react-bootstrap": "^1.4.3",
17 | "react-dom": "^16.12.0",
18 | "react-router-dom": "^5.1.2",
19 | "react-scripts": "3.3.1"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": "react-app"
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/backend/models/Jobs.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const JobsSchema = new Schema({
5 | title: {
6 | type: String,
7 | required: true
8 | },
9 | name_recruiter: {
10 | type: String,
11 | required: true
12 | },
13 | email_recruiter: {
14 | type: String,
15 | required: true
16 | },
17 | max_applications: {
18 | type: Number,
19 | required: true
20 | },
21 | max_positions: {
22 | type: Number,
23 | required: true
24 | },
25 | number_of_positions_filled: {
26 | type: Number,
27 | required: false,
28 | default: 0
29 | },
30 | date_of_posting: {
31 | type: Date,
32 | required: false
33 | },
34 | deadline_of_application: {
35 | type: Date,
36 | required: true
37 | },
38 | required_skills: {
39 | type: String,
40 | required: true
41 | },
42 | type_of_job: {
43 | type: String,
44 | required: true
45 | },
46 | duration: {
47 | type: Number,
48 | required: true,
49 | // default: 0
50 | // min: 0,
51 | // max: 7
52 | },
53 | salary_per_month: {
54 | type: Number,
55 | required: true
56 | },
57 | rating: {
58 | type: Number,
59 | required: false,
60 | default: 0
61 | },
62 | rate_count:{
63 | type:Number,
64 | default:0,
65 | required:false,
66 | },
67 | status: {
68 | type: String,
69 | required: false,
70 | default: "present"
71 | }
72 | });
73 |
74 | module.exports = Job = mongoose.model("Jobs", JobsSchema);
--------------------------------------------------------------------------------
/frontend/src/components/Common/styles.css:
--------------------------------------------------------------------------------
1 | /* Add a black background color to the top navigation */
2 | .topnav {
3 | background-color: #333;
4 | overflow: hidden;
5 | }
6 |
7 | .bt1 {
8 | background-color: #f44336;
9 | border: none;
10 | color: white;
11 | padding: 15px 32px;
12 | text-align: center;
13 | text-decoration: none;
14 | display: inline-block;
15 | font-size: 14px;
16 | border-radius: 12px;
17 | }
18 |
19 | .bt2 {
20 | background-color: #008CBA;
21 | border: none;
22 | color: white;
23 | padding: 15px 32px;
24 | text-align: center;
25 | text-decoration: none;
26 | display: inline-block;
27 | font-size: 14px;
28 | border-radius: 12px;
29 | }
30 |
31 | /* Style the links inside the navigation bar */
32 | .topnav a {
33 | float: left;
34 | color: #f2f2f2;
35 | text-align: center;
36 | padding: 14px 16px;
37 | text-decoration: none;
38 | font-size: 17px;
39 | }
40 |
41 | /* Change the color of links on hover */
42 | .topnav a:hover {
43 | background-color: #ddd;
44 | color: black;
45 | }
46 |
47 | /* Add a color to the active/current link */
48 | .topnav a.active {
49 | background-color: #4CAF50;
50 | color: white;
51 | }
52 |
53 | .topnav input[type=text] {
54 | float: right;
55 | padding: 6px;
56 | border: none;
57 | margin-top: 8px;
58 | margin-right: 16px;
59 | font-size: 17px;
60 | }
--------------------------------------------------------------------------------
/frontend/src/components/Users/Profile.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import Paper from '@material-ui/core/Paper';
4 | import Grid from '@material-ui/core/Grid';
5 | import TableCell from '@material-ui/core/TableCell';
6 | import TableHead from '@material-ui/core/TableHead';
7 | import TableRow from '@material-ui/core/TableRow';
8 | import Table from '@material-ui/core/Table';
9 | import TableBody from '@material-ui/core/TableBody';
10 | import Button from '@material-ui/core/Button';
11 | import Typography from '@material-ui/core/Typography';
12 | import Slider from '@material-ui/core/Slider';
13 |
14 |
15 | import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
16 | import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
17 |
18 | class Profile extends Component {
19 |
20 | constructor(props) {
21 | super(props);
22 | this.state = {users: [],sortName:true};
23 | // this.sortClicked = this.sortClicked.bind(this);
24 | // this.renderIcon = this.renderIcon.bind(this);
25 | // this.sortChange = this.sortChange.bind(this);
26 | }
27 |
28 | render() {
29 | return (
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | )
38 | }
39 | }
40 |
41 | export default Profile;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # job-portal
2 |
3 | ## DASS(design and analysis of software systems) (a mern stack app) | spring 2021
4 |
5 | ## Installations
6 |
7 | ### Node
8 |
9 | * For Linux:
10 | ```
11 | curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
12 | sudo apt-get install -y nodejs
13 | ```
14 |
15 | * For Mac:
16 | ```
17 | brew install node
18 | ```
19 |
20 | ### MongoDB
21 |
22 | Install the community edition [here](https://docs.mongodb.com/manual/installation/#mongodb-community-edition-installation-tutorials).
23 |
24 | ### React
25 |
26 | ```
27 | npm install -g create-react-app
28 | ```
29 |
30 | ## Running the code
31 |
32 | * Run Mongo daemon:
33 | ```
34 | sudo mongod
35 | ```
36 | Mongo will be running on port 27017.
37 |
38 |
39 | * Run Express Backend:
40 | ```
41 | cd backend/
42 | npm install
43 | npm start
44 | ```
45 |
46 | * Run React Frontend (open a different terminal):
47 | ```
48 | cd frontend/
49 | npm install
50 | npm start
51 | ```
52 |
53 | Navigate to [http://localhost:3000/](http://localhost:3000/) in your browser.
54 |
55 | ## Contributions:
56 | You are invited to contribute to this project by adding a PR. If genuine, the changes would be approved and added to the master branch.
57 |
58 | ### can work on:
59 | * rating feature (applicant should be able to rate job, similar to applicant rating by recruiter).
60 | * login via facebook or google.
61 | * show profile picture.
62 | * download cv button on recruiter side,
63 | * edit job has some minor problems.
64 | * anything else you can find intresting, open for suggession.
65 |
--------------------------------------------------------------------------------
/frontend/src/components/templates/Navbar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
3 | import "bootstrap/dist/css/bootstrap.min.css"
4 |
5 | export default class NavBar extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
33 |
34 | )
35 | }
36 | }
--------------------------------------------------------------------------------
/frontend/src/components/templates/Applicant_navbar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
3 | import "bootstrap/dist/css/bootstrap.min.css"
4 |
5 | export default class Applicant_navbar extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
36 |
37 | )
38 | }
39 | }
--------------------------------------------------------------------------------
/backend/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const bodyParser = require('body-parser');
4 | const cors = require('cors');
5 | const path = require('path');
6 | const mongoose = require('mongoose');
7 | const PORT = 4000;
8 | const DB_NAME = "tutorial"
9 |
10 | // routes
11 | var testAPIRouter = require("./routes/testAPI");
12 | var UserRouter = require("./routes/Users");
13 | //var UserrrrRouter = require("./routes/Recruiters");
14 | var RecruiterRouter =require("./routes/Recruiters");
15 | var JobRouter=require("./routes/Jobs");
16 | var ApplicationRouter=require("./routes/application");
17 | var ApplicantRouter=require("./routes/Applicant");
18 |
19 | app.use('/image',express.static(path.join(__dirname, 'public/image')));
20 | app.use('/cv',express.static(path.join(__dirname, 'public/cv')));
21 | app.use(cors());
22 | app.use(bodyParser.json());
23 | app.use(bodyParser.urlencoded({ extended: true }));
24 |
25 | // Connection to MongoDB
26 | mongoose.connect('mongodb+srv://palash:spaceword@cluster0.ofm4x.mongodb.net/mlh-abracadabra?retryWrites=true&w=majority', { useNewUrlParser: true, useUnifiedTopology: true });
27 | const connection = mongoose.connection;
28 | connection.once('open', function() {
29 | console.log("MongoDB database connection established successfully !");
30 | })
31 |
32 | // setup API endpoints
33 | app.use("/testAPI", testAPIRouter);
34 | app.use("/user", UserRouter);
35 | //app.use("/router", UserrrrRouter);
36 | app.use("/recruiter", RecruiterRouter);
37 | app.use("/job",JobRouter);
38 | app.use("/application",ApplicationRouter)
39 | app.use("/applicant",ApplicantRouter)
40 |
41 | app.listen(PORT, function() {
42 | console.log("Server is running on Port: " + PORT);
43 | });
44 |
--------------------------------------------------------------------------------
/backend/models/applications.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Schema = mongoose.Schema;
3 |
4 | const Applicationschema = new Schema({
5 | job_id:{
6 | type: String,
7 | required: false,
8 | },
9 | recruiter_email:{
10 | type: String,
11 | required: false,
12 | },
13 | applicant_email:{
14 | type: String,
15 | required: false,
16 | },
17 | status:{
18 | type:String,
19 | required:false,
20 | // default:
21 | },
22 | sop:{
23 | type: String,
24 | required: false
25 | },
26 | date_of_application:{
27 | type: Date,
28 | required: false,
29 | default:Date.now()
30 | },
31 | job_salary_per_month:{
32 | type: Number,
33 | required: false
34 | },
35 | name_recrutier:{
36 | type:String,
37 | required:false
38 | },
39 | status_of_job:{
40 | type:String,
41 | required: false
42 | },
43 | job_title:{
44 | type:String,
45 | required:false,
46 | },
47 | stage_of_application:{
48 | type:String,
49 | required:false,
50 | },
51 | name_applicant:{
52 | type:String,
53 | required:false,
54 | },
55 | skills_applicant:{
56 | type:String,
57 | required:false,
58 | },
59 | education_applicant:{
60 | type:[],
61 | required:false,
62 | },
63 | applicant_rating:{
64 | type:Number,
65 | required:false,
66 | default:0,
67 | },
68 | job_type:{
69 | type:String,
70 | required:false,
71 | },
72 | date_of_joining:{
73 | type:Date,
74 | required:false,
75 | }
76 | })
77 |
78 | module.exports = Application = mongoose.model("applications", Applicationschema);
--------------------------------------------------------------------------------
/frontend/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/frontend/src/components/templates/Recruiter_navbar.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
3 | import "bootstrap/dist/css/bootstrap.min.css"
4 |
5 | export default class Recruiter_navbar extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | }
10 |
11 | render() {
12 | return (
13 |
14 |
38 |
39 | )
40 | }
41 | }
--------------------------------------------------------------------------------
/backend/routes/Recruiters.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 |
4 | // Load model
5 | const User = require("../models/Users");
6 | const Recruiter = require("../models/recruiters");
7 | const Applicant = require("../models/applicants");
8 | const Job = require("../models/Jobs");
9 | const Application = require("../models/applications");
10 |
11 | router.get("/s", function(req, res) {
12 | res.send("API is working properly !");
13 | });
14 |
15 | // Getting all the recruiters
16 | router.get("/recruiter", function(req, res) {
17 | Recruiter.find(function(err, recruiters) {
18 | if (err) {
19 | console.log(err);
20 | } else {
21 | res.json(recruiters);
22 | }
23 | })
24 | });
25 |
26 | // get a recruiter by his email
27 | router.post("/get_a_recruiter_by_email",(req,res) => {
28 | var email = req.body.email;
29 | var query = { email: email };
30 | Recruiter.findOne(query, function(err , resp){
31 | if (err) throw err;
32 | })
33 | .then(resp => {
34 | res.status(200).json(resp);
35 | console.log(resp);
36 | return resp;
37 | })
38 | });
39 |
40 |
41 | // Add a recruiter to db
42 | router.post("/recruiter/add", (req, res) => {
43 | const newRecruiter = new Recruiter({
44 | name: req.body.name,
45 | email: req.body.email,
46 | password: req.body.password,
47 | type: req.body.type,
48 | date: req.body.date,
49 | bio: req.body.bio_recruiter,
50 | contact_number: req.body.contact_number,
51 | });
52 | newRecruiter.save()
53 | .then(recruiter => {
54 | res.status(200).json(recruiter);
55 | })
56 | .catch(err => {
57 | res.status(400).send(err);
58 | });
59 | });
60 |
61 | //edit recruiter profile
62 | router.post('/edit_recruiter_profile', (req, res) => {
63 | console.log(req);
64 | var query = {email:req.body.email };
65 | var set = { $set:{
66 | bio: req.body.bio,
67 | contact_number: req.body.contact_number,
68 | name: req.body.name,
69 | }}
70 | Recruiter.updateOne(query , set, function(err, resp){
71 | if (err) throw err;
72 | })
73 | .then(resp => {
74 | res.status(200).json(resp);
75 | console.log(resp);
76 | return resp;
77 | });
78 | });
79 |
80 |
81 |
82 |
83 | module.exports = router;
--------------------------------------------------------------------------------
/frontend/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/backend/routes/Users.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 |
4 | // Load User model
5 | const User = require("../models/Users");
6 |
7 | // GET request
8 | // Getting all the users
9 | router.get("/s", function(req, res) {
10 | res.send("API is working properly !");
11 | });
12 |
13 | router.get("/user", function(req, res) {
14 | User.find(function(err, users) {
15 | if (err) {
16 | console.log(err);
17 | } else {
18 | res.json(users);
19 | }
20 | })
21 | });
22 |
23 | // Add a user to db
24 | // router.post("/user/add", (req, res) => {
25 | // const newUser = new User({
26 | // name: req.body.name,
27 | // email: req.body.email,
28 | // password: req.body.password,
29 | // type: req.body.type,
30 | // date: req.body.date
31 | // });
32 | // newUser.save()
33 | // .then(user => {
34 | // res.status(200).json(user);
35 | // })
36 | // .catch(err => {
37 | // res.status(400).send(err);
38 | // });
39 | // });
40 | router.post("/updateuser", (req, res) => {
41 | console.log(req.body.email)
42 | console.log(req.body.name)
43 | var query = { email:req.body.email };
44 | var set = { $set:{
45 | name: req.body.name,
46 | }}
47 | User.updateOne(query , set, function(err, resp){
48 | if (err) throw err;
49 | })
50 | .then(resp => {
51 | res.status(200).json(resp);
52 | console.log(resp);
53 |
54 | });
55 | })
56 |
57 |
58 |
59 | // POST request
60 | // Add a user to db
61 | router.post("/register", (req, res) => {
62 | const newUser = new User({
63 | name: req.body.name,
64 | email: req.body.email,
65 | password: req.body.password,
66 | type: req.body.type,
67 | date: req.body.date
68 | });
69 |
70 | newUser.save()
71 | .then(user => {
72 | res.status(200).json(user);
73 | })
74 | .catch(err => {
75 | res.status(400).send(err);
76 | });
77 | });
78 |
79 | // POST request
80 | // Login
81 | router.post("/login", (req, res) => {
82 | const email = req.body.email;
83 | // Find user by email
84 | User.findOne({ email }).then(user => {
85 | // Check if user email exists
86 | if (!user) {
87 | return res.status(404).json({
88 | error: "Email not found",
89 | });
90 | }
91 | else{
92 | res.status(200).json(user);
93 | console.log(user);
94 | return user;
95 | }
96 | });
97 | });
98 |
99 |
100 | module.exports = router;
101 |
102 |
--------------------------------------------------------------------------------
/frontend/src/components/Common/login.css:
--------------------------------------------------------------------------------
1 | body{
2 | background-image:url("./cool-background.png");
3 | background-repeat: no-repeat;
4 | background-size: cover;
5 |
6 | }
7 | .hero-image {
8 |
9 | height: 500px;
10 | position: relative;
11 | animation: fadeIn 2s;
12 | animation-fill-mode: forwards;
13 | }
14 |
15 | .hero-text {
16 | text-align: center;
17 | position: absolute;
18 | top: 50%;
19 | left: 50%;
20 | transform: translate(-50%, -50%);
21 | color: black;
22 | }
23 | @keyframes fadeIn {
24 | 0% {
25 | opacity: 0;
26 | }
27 | 100% {
28 | opacity: 1;
29 | }
30 | }
31 |
32 | @keyframes fadeOut {
33 | 0%, 100% {
34 | opacity: 1;
35 | }
36 | 15%, 85% {
37 | opacity: 0;
38 | }
39 | }
40 |
41 | @keyframes lumos {
42 | 50% {
43 | transform: scale(3);
44 | box-shadow: 0px 0px 45px 45px white;
45 | }
46 | }
47 |
48 | @keyframes lumosMaxima {
49 | 35% {
50 | transform: scale(5);
51 | box-shadow: 0px 0px 80px 80px white;
52 | }
53 | 50% {
54 | transform: scale(5);
55 | box-shadow: 0px 0px 75px 75px white;
56 | }
57 | 85% {
58 | transform: scale(5);
59 | box-shadow: 0px 0px 85px 85px white;
60 | }
61 | }
62 |
63 | #dumbledore {
64 | position: absolute;
65 | top:0;
66 | bottom: 0;
67 | left: 0;
68 | right: 0;
69 | margin: auto;
70 | display: flex;
71 | flex-direction: column;
72 | align-items: center;
73 | justify-content: center;
74 | }
75 |
76 | .quote {
77 | color: black;
78 | text-align: center;
79 | font-family: 'Tangerine', cursive;
80 | font-size: 3em;
81 | margin: 10px;
82 | opacity: 0;
83 | animation: fadeIn 5s;
84 | animation-fill-mode: forwards;
85 |
86 | }
87 |
88 | #part2.quote {
89 | animation-delay: 1s;
90 | }
91 |
92 | #part3.quote {
93 | animation-delay: 2s;
94 | }
95 |
96 | #light {
97 | position: absolute;
98 | top:0;
99 | bottom: 0;
100 | left: 0;
101 | right: 0;
102 | margin: auto;
103 | height: 1px;
104 | width: 1px;
105 | border-radius: 50%;
106 | background-color: #13324d;
107 |
108 | }
109 |
110 | .faded {
111 | animation: fadeOut 5s;
112 | animation-timing-function: ease-in-out;
113 | }
114 |
115 | .lumos {
116 | background: radial-gradient(circle, rgba(255,251,241,1) 0%, rgba(255,255,254,1) 11%);
117 | animation: lumos 5s;
118 | animation-timing-function: ease-in-out;
119 | }
120 |
121 | .lumosMaxima {
122 | background: radial-gradient(circle, rgba(255,251,241,1) 0%, rgba(255,255,254,1) 11%);
123 | animation: lumosMaxima 5s;
124 | animation-timing-function: ease-in-out;
125 |
126 | }
127 |
128 | #code {
129 | position: absolute;
130 | bottom: 0;
131 | right: 0;
132 | margin-right: 15px;
133 | margin-bottom: 15px;
134 | font-size: 15px;
135 | font-family: 'Hepta Slab', serif;
136 | color: #fcba03;
137 | }
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
2 |
3 | ## Available Scripts
4 |
5 | In the project directory, you can run:
6 |
7 | ### `yarn start`
8 |
9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
11 |
12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console.
14 |
15 | ### `yarn test`
16 |
17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
19 |
20 | ### `yarn build`
21 |
22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance.
24 |
25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed!
27 |
28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
29 |
30 | ### `yarn eject`
31 |
32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
33 |
34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
35 |
36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
37 |
38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
39 |
40 | ## Learn More
41 |
42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
43 |
44 | To learn React, check out the [React documentation](https://reactjs.org/).
45 |
46 | ### Code Splitting
47 |
48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
49 |
50 | ### Analyzing the Bundle Size
51 |
52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
53 |
54 | ### Making a Progressive Web App
55 |
56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
57 |
58 | ### Advanced Configuration
59 |
60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
61 |
62 | ### Deployment
63 |
64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
65 |
66 | ### `yarn build` fails to minify
67 |
68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
69 |
--------------------------------------------------------------------------------
/frontend/src/components/Common/my_applications.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import "bootstrap/dist/css/bootstrap.min.css";
4 | import Button from 'react-bootstrap/Button'
5 |
6 | export default class My_applications extends Component {
7 |
8 | constructor(props) {
9 | super(props);
10 | // this.deletejob = this.deletejob.bind(this)
11 | this.state = {
12 | listings: []
13 | }
14 | }
15 |
16 | componentDidMount() {
17 | if(localStorage.getItem('user_type') === "applicant" && localStorage.getItem('isloggedin') === "true" ){
18 | let email = localStorage.getItem('user_email');
19 | const data_rec = {
20 | email_rec: email
21 | };
22 | axios.post('http://localhost:4000/application/all_my_applications', data_rec)
23 | .then(response => {
24 | console.log(response.data)
25 | this.setState({listings: response.data});
26 | })
27 | .catch(function(error) {
28 | // if(error.response.data.message)
29 | // alert(error.response.data.message);
30 | console.log(error);
31 | })
32 | }
33 | else{
34 | alert("login first");
35 | this.props.history.push("/");
36 | window.location.reload();
37 | }
38 | }
39 |
40 |
41 | rate_recruiter(id) {
42 |
43 | }
44 |
45 | rate_recruiter = this.rate_recrutier;
46 |
47 | render() {
48 | return (
49 |
50 |
51 |
52 |
53 | | job title |
54 | date of joining |
55 | salary per month |
56 | status of job |
57 | rate |
58 |
59 |
60 |
61 | {
62 | this.state.listings.map((application, i) => {
63 | var vivi = null;
64 | if(application.status === "accepted"){
65 | vivi = |
66 | }
67 | return (
68 |
69 | | {application.job_title} |
70 | {application.date_of_joining} |
71 | {application.job_salary_per_month} |
72 | {application.status} |
73 | {/* | */}
74 | {vivi}
75 |
76 | )
77 | })
78 | }
79 |
80 |
81 |
82 | )
83 | }
84 | }
--------------------------------------------------------------------------------
/frontend/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
3 | import "bootstrap/dist/css/bootstrap.min.css"
4 |
5 | import UsersList from './components/Users/UsersList'
6 | import Home from './components/Common/Home'
7 | import Register from './components/Common/Register'
8 | import Profileedit_recruiter from './components/Common/Profileedit_recruiter'
9 | import Profileedit_applicant from './components/Common/Profileedit_applicant'
10 | import Navbar from './components/templates/Navbar'
11 | import Applicant_navbar from './components/templates/Applicant_navbar'
12 | import Profile from './components/Users/Profile'
13 | import Login from './components/Common/Login'
14 | import Recruiter_navbar from './components/templates/Recruiter_navbar';
15 | import Add_job from './components/Common/Add_jobs';
16 | import Viewjoblisting from './components/Common/Joblistings';
17 | import View_job_listings_applicant from './components/Common/View_job_listings_applicant';
18 | import Job_info from './components/Common/Job_info';
19 | import My_applications from './components/Common/my_applications';
20 | import Job_application_info from './components/Common/job_application_info_rec';
21 | import Edit_job from './components/Common/Edit-job';
22 | import My_employees from './components/Common/my_employees';
23 | import Rate_applicant from './components/Common/rate_my_employee';
24 |
25 |
26 | class App extends React.Component{
27 | render(){
28 | let user_type = localStorage.getItem('user_type');
29 | let navbar = null;
30 | console.log(user_type);
31 | if(user_type === "applicant"){
32 | console.log("applicant");
33 | navbar = ;
34 | }
35 | else if(user_type === "recruiter"){
36 | console.log("recruiter");
37 | navbar = ;
38 | }
39 | else{
40 | console.log("lul");
41 | navbar =
42 | }
43 | return (
44 |
45 |
46 | {navbar}
47 |
48 |
{
49 | if(user_type === "applicant"){
50 | console.log("111111");
51 | return
52 | }
53 | else if(user_type === "recruiter"){
54 | return
55 | }
56 | else{
57 | return
58 | }
59 | }} />
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | );
79 | }
80 | }
81 |
82 | export default App;
--------------------------------------------------------------------------------
/frontend/src/components/Common/Joblistings.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import "bootstrap/dist/css/bootstrap.min.css";
4 | import Button from 'react-bootstrap/Button'
5 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
6 |
7 |
8 | export default class Joblistings extends Component {
9 |
10 | constructor(props) {
11 | super(props);
12 | // this.deletejob = this.deletejob.bind(this)
13 | this.state = {
14 | listings: []
15 | }
16 | }
17 |
18 | componentDidMount() {
19 | if(localStorage.getItem('user_type') === "recruiter" && localStorage.getItem('isloggedin') === "true" ){
20 | let email = localStorage.getItem('user_email');
21 | const data_rec = {
22 | email_rec: email
23 | };
24 | axios.post('http://localhost:4000/job/job/view', data_rec)
25 | .then(response => {
26 | console.log(response.data)
27 | this.setState({listings: response.data});
28 | })
29 | .catch(function(error) {
30 | console.log(error);
31 | })
32 | }
33 | else{
34 | alert("login first");
35 | this.props.history.push("/");
36 | window.location.reload();
37 | }
38 | }
39 |
40 |
41 | deletejob(id) {
42 | axios.post('http://localhost:4000/job/job/delete',{'id': id})
43 | .then(response => {
44 | console.log(response.data)
45 | });
46 | this.setState({
47 | listings: this.state.listings.filter(el => el._id !== id)
48 | })
49 | }
50 |
51 | deletejob = this.deletejob;
52 |
53 | render() {
54 | return (
55 |
56 |
57 |
58 |
59 | | title |
60 | date of posting |
61 | number of applicants |
62 | maximum number of positions |
63 | delete |
64 |
65 |
66 |
67 | {
68 | this.state.listings.map((job, i) => {
69 | const kaha_jana = {
70 | pathname: "/job-listings/"+job._id
71 | }
72 | const jana_kaha = {
73 | pathname: "/edit-job/"+job._id
74 | }
75 | return (
76 |
77 | | {job.title} |
78 | {job.date_of_posting} |
79 | {job.max_applications} |
80 | {job.max_positions} |
81 | |
82 | |
83 |
84 | |
85 |
86 | )
87 | })
88 | }
89 |
90 |
91 |
92 | )
93 | }
94 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/Login.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import bcrypt from 'bcryptjs';
4 | import { BrowserRouter as Router, Route, Link } from "react-router-dom";
5 | import './login.css';
6 |
7 |
8 |
9 | export default class Login extends Component {
10 |
11 | constructor(props) {
12 | super(props);
13 |
14 | this.state = {
15 | email: '',
16 | password: ''
17 | }
18 |
19 | this.onChangeEmail = this.onChangeEmail.bind(this);
20 | this.onChangePassword = this.onChangePassword.bind(this);
21 | this.addUser = this.addUser.bind(this);
22 | }
23 |
24 | onChangeEmail(event){
25 | this.setState({ email: event.target.value })
26 | }
27 |
28 | onChangePassword(event){
29 | this.setState({ password: event.target.value })
30 | }
31 |
32 | addUser(event) {
33 | event.preventDefault();
34 | const userAdd = {
35 | email: this.state.email,
36 | password: this.state.password
37 | // type: this.state.type
38 | }
39 | console.log(userAdd)
40 | axios.post('http://localhost:4000/user/login', userAdd)
41 | .then(res => {
42 | var temper = bcrypt.compareSync(userAdd.password,res.data.password);
43 | console.log(res);
44 | if (res.data.email===userAdd.email && temper) {
45 | alert("hii");
46 | console.log(res.data);
47 | localStorage.setItem('user_type', res.data.type);
48 | localStorage.setItem('user_name', res.data.name);
49 | localStorage.setItem('user_id',res.data._id);
50 | localStorage.setItem('isloggedin',true);
51 | localStorage.setItem('user_email', res.data.email);
52 | if(res.data.type == 'applicant'){
53 | const temp = {
54 | applicant_ka_email: res.data.email
55 | };
56 | axios.post('http://localhost:4000/applicant/get_an_applicant_by_email', temp).then((res) => {
57 | console.log(res.data, 'is the data');
58 | localStorage.setItem('user_image', res.data.image);
59 | console.log("this is the image we wanted ", localStorage.getItem('user_image'));
60 | window.location = '/';
61 |
62 | }).catch(err => {
63 | console.log(res);
64 | console.log(err);
65 | });
66 | } else {
67 | window.location = '/';
68 | }
69 | // this.props.history.push("/");
70 | }
71 | else {
72 | alert("Invalid Password")
73 | }
74 | })
75 | .catch(err => {
76 | alert("user not found");
77 | console.log(err)
78 | });
79 | }
80 |
81 |
82 | render() {
83 | return (
84 | < div className="login">
85 | Login Page
86 |
110 |
111 |
112 | )
113 | }
114 | }
--------------------------------------------------------------------------------
/backend/routes/Applicant.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 | const multer = require("multer");
4 | const path = require("path");
5 | const Applicant = require("../models/applicants");
6 |
7 | router.get("/s", function(req, res) {
8 | res.send("API is working properly !");
9 | });
10 | // Getting all the applicants
11 | router.get("/applicant", function(req, res) {
12 | Applicant.find(function(err, applicants) {
13 | if (err) {
14 | console.log(err);
15 | } else {
16 | res.json(applicants);
17 | }
18 | })
19 | });
20 |
21 | // get a applicant by his email
22 | router.post("/get_an_applicant_by_email",(req,res) => {
23 | var email = req.body.applicant_ka_email;
24 | var query = { email: email };
25 | Applicant.findOne(query, function(err , resp){
26 | if (err) throw err;
27 | })
28 | .then(resp => {
29 | res.status(200).json(resp).send();
30 | console.log('get_an_applicant_by_email ka response is ', resp);
31 | // return resp;
32 | })
33 | });
34 |
35 | // Add a applicant to db
36 | router.post("/applicant/add", (req, res) => {
37 | const newApplicant = new Applicant({
38 | name: req.body.name,
39 | email: req.body.email,
40 | password: req.body.password,
41 | type: req.body.type,
42 | date: req.body.date,
43 | list_of_languages: req.body.list_of_languages,
44 | education: req.body.education,
45 | image: req.body.image,
46 | cv:req.body.cv
47 | });
48 | newApplicant.save()
49 | .then(applicant => {
50 | res.status(200).json(applicant);
51 | })
52 | .catch(err => {
53 | res.status(400).send(err);
54 | });
55 | });
56 | //edit applicant's profile
57 | router.post('/edit_applicant_profile', (req, res) => {
58 | console.log(req);
59 | var query = {email:req.body.email };
60 | var set = { $set:{
61 | name: req.body.name,
62 | list_of_languages: req.body.list_of_languages,
63 | education: req.body.education,
64 | // image: req.body.image,
65 | cv:req.body.cv
66 | }}
67 | Applicant.updateOne(query , set, function(err, resp){
68 | if (err) throw err;
69 | })
70 | .then(resp => {
71 | res.status(200).json(resp);
72 | console.log(resp);
73 | return resp;
74 | });
75 | });
76 |
77 | // Login
78 |
79 |
80 | // rate an applicant by recruiter
81 | router.post("/rate_an_applicant",(req,res) => {
82 | console.log(req)
83 | var email = req.body.email;
84 | var query = { email: email };
85 | var set = { rate_count: req.body.rate_count , rating:req.body.rating };
86 | Applicant.updateOne(query , set , function(err , resp){
87 | if (err) throw err;
88 | })
89 | .then(resp => {
90 | // var sett = { $divide: [ { $inc: {rating: req.body.value} } , resp.data.rate_count ]};
91 | // Applicant.updateOne(query , sett , function(err,respon){
92 | // if(err) throw err;
93 | // })
94 | console.log(resp.applicant_email)
95 | res.status(200).json(resp);
96 | console.log(resp);
97 | return resp;
98 | })
99 | });
100 | //increment application count of applicant
101 | router.post("/increment_application_count",(req,res) => {
102 | var email = req.body.email;
103 | var query = { email: email };
104 | var set = { $inc: { application_count: 1 } };
105 | Applicant.updateOne(query , set , function(err , resp){
106 | if (err) throw err;
107 | })
108 | .then(resp => {
109 | console.log(resp.applicant_email)
110 | res.status(200).json(resp);
111 | console.log(resp);
112 | return resp;
113 | })
114 | });
115 |
116 | //decrement application count of applicant
117 | router.post("/decrement_application_count",(req,res) => {
118 | var email = req.body.email;
119 | var query = { email: email };
120 | var set = { $inc: { application_count: -1 } };
121 | Applicant.updateOne(query , set , function(err , resp){
122 | if (err) throw err;
123 | })
124 | .then(resp => {
125 | console.log(resp.applicant_email)
126 | res.status(200).json(resp);
127 | // console.log(resp);
128 | return resp;
129 | })
130 | });
131 |
132 | var storage = multer.diskStorage({
133 | destination: function (req, file, cb) {
134 | cb(null, "public/" + req.query.type);
135 | },
136 | filename: function (req, file, cb) {
137 | // this is where the book receives its distinct file_name structure
138 | fileName = req.query.email + path.extname(file.originalname);
139 | if(req.query.type == 'image'){
140 | Applicant.updateOne({email:req.query.email}, {
141 | $set: {image: fileName}
142 | }, err => {
143 | console.log(err);
144 | });
145 | }
146 | cb(
147 | null,
148 | fileName
149 | );
150 | },
151 | });
152 |
153 | // renaming the multer function as upload
154 | var upload = multer({ storage: storage });
155 |
156 | // send request with parameter id to add the cv
157 | router.post("/addfile", upload.single('file'), (req,res)=>{
158 | console.log("adding file");
159 | let userid = req.query.email;
160 | let type = req.query.type;
161 | console.log("got this ", userid, type);
162 | res.status(200).send();
163 | });
164 |
165 | module.exports = router;
--------------------------------------------------------------------------------
/frontend/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl, {
104 | headers: { 'Service-Worker': 'script' }
105 | })
106 | .then(response => {
107 | // Ensure service worker exists, and that we really are getting a JS file.
108 | const contentType = response.headers.get('content-type');
109 | if (
110 | response.status === 404 ||
111 | (contentType != null && contentType.indexOf('javascript') === -1)
112 | ) {
113 | // No service worker found. Probably a different app. Reload the page.
114 | navigator.serviceWorker.ready.then(registration => {
115 | registration.unregister().then(() => {
116 | window.location.reload();
117 | });
118 | });
119 | } else {
120 | // Service worker found. Proceed as normal.
121 | registerValidSW(swUrl, config);
122 | }
123 | })
124 | .catch(() => {
125 | console.log(
126 | 'No internet connection found. App is running in offline mode.'
127 | );
128 | });
129 | }
130 |
131 | export function unregister() {
132 | if ('serviceWorker' in navigator) {
133 | navigator.serviceWorker.ready.then(registration => {
134 | registration.unregister();
135 | });
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/backend/routes/application.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 | var mongoose = require('mongoose');
4 | const Application = require("../models/applications");
5 | const { route } = require("./application");
6 |
7 | router.get("/s", function(req, res) {
8 | res.send("API is working properly !");
9 | });
10 | // add an application by applicant
11 | router.post("/addapplication",(req,res) => {
12 | var lol = new Application({
13 | job_id: req.body.job_id,
14 | recruiter_email: req.body.email_recruiter,
15 | applicant_email: req.body.applicant_email,
16 | status: req.body.status,
17 | sop: req.body.sop,
18 | date_of_application: Date.now(),
19 | name_recruiter: req.body.name_recruiter,
20 | job_salary_per_month: req.body.job_salary_per_month,
21 | status_of_job: req.body.status_of_job,
22 | job_title: req.body.job_title,
23 | name_applicant: req.body.name_applicant,
24 | skills_applicant: req.body.skills,
25 | education_applicant: req.body.education,
26 | job_type: req.body.job_type,
27 | applicant_rating:req.body.rating
28 | });
29 | lol.save()
30 | .then(resp => {
31 | res.status(200).json(resp);
32 | console.log(resp);
33 | return resp;
34 | })
35 | var query = { _id: req.body.job_id };
36 | set = { $inc: { number_of_positions_filled: 1 } };
37 | Job.updateOne(query , set , function(err , resp){
38 | if(err) throw err;
39 | })
40 | .then(resp => {
41 | res.status(200).json(resp);
42 | console.log(resp);
43 | return resp;
44 | })
45 | });
46 |
47 | //check if an application is present or not
48 | router.post("/app_p_or_n",(req,res)=>{
49 | Application.find( { "applicant_email":req.body.applicant_email,"job_id":req.body.id } ).then(app=> {
50 | console.log("yes");
51 | console.log(req.body)
52 | res.json(app); //get applicant ids from it
53 | console.log(app.status)
54 | })
55 | .catch(err => {
56 | res.status(400).send(err);
57 | });
58 | });
59 |
60 | //all applied job by an perticular applicant
61 | router.post("/all_applied_jobs",(req,res)=>{
62 | Application.find( { "applicant_email":req.body.applicant_email} ).then(app=> {
63 | console.log("yes");
64 | res.send(app) //get applicant ids from it
65 | console.log(app.status)
66 | })
67 | .catch(err => {
68 | res.status(400).send(err);
69 | });
70 | });
71 |
72 | //all selected employees by a perticular recruiter
73 | router.post("/all_my_employees",(req,res)=>{
74 | Application.find({recruiter_email: req.body.email_rec, status: "accepted" } ).then(app=> {
75 | console.log("yes");
76 | res.send(app) //get applicant ids from it
77 | console.log(app.status)
78 | })
79 | .catch(err => {
80 | res.status(400).send(err);
81 | });
82 | });
83 |
84 | // getting all the applications
85 | router.get("/allapplications", function(req, res) {
86 | Application.find(function(err, applications) {
87 | if (err) {
88 | console.log(err);
89 | } else {
90 | res.json(applications);
91 | }
92 | })
93 | });
94 |
95 | //all the applications of a perticular applicant
96 | router.post("/all_my_applications", function(req, res) {
97 | Application.find( {"applicant_email":req.body.email_rec} ,function(err, applications) {
98 | if (err) {
99 | console.log(err);
100 | } else {
101 | res.json(applications);
102 | }
103 | })
104 | });
105 |
106 | // getting all non rejected applications posted by a perticular recruiter
107 | router.post("/all_my_non-rejected_applications_of_perticular_job", function(req, res) {
108 | Application.find( { $and: [{ recruiter_email:req.body.email_recruiter}, {job_id: req.body.id} ,{ $or: [ {status: "applied"} ,{ status: "shortlisted" },{ status: "accepted" } ] }]} ,function(err, applications) {
109 | if (err) {
110 | console.log(err);
111 | } else {
112 | res.json(applications);
113 | }
114 | })
115 | });
116 |
117 | //accept an application by id
118 | router.post("/accept_an_application",(req,res) => {
119 | var id = req.body.id;
120 | console.log(req.body);
121 | var query = { _id: id };
122 | var set = { $set: { status: "accepted" } };
123 | Application.updateMany(query , set , function(err , resp){
124 | if (err) throw err;
125 | })
126 | .then(resp => {
127 | Application.findOne(query ).then( (respon) => {
128 | console.log(respon);
129 | var gg = respon.applicant_email;
130 | var nodemailer = require('nodemailer');
131 | var transporter = nodemailer.createTransport({
132 | service: 'gmail',
133 | auth: {
134 | user: 'job.dalaaaliii@gmail.com',
135 | pass: 'veeral veeral'
136 | }
137 | });
138 | var mailOptions = {
139 | from: 'job.dalaaaliii@gmail.com',
140 | to: gg,
141 | subject: 'application accepted',
142 | text: 'wow bhaiya ;)'
143 | };
144 | transporter.sendMail(mailOptions, function(error, info){
145 | if (error) {
146 | console.log(error);
147 | } else {
148 | console.log('Email sent');
149 | }
150 | })
151 | })
152 | })
153 | });
154 |
155 | //reject an application by id
156 | router.post("/reject_an_application",(req,res) => {
157 | var id = req.body.id;
158 | var query = { _id: id };
159 | var set = { $set: { status: "rejected" } };
160 | Application.updateMany(query , set , function(err , resp){
161 | if (err) throw err;
162 | })
163 | .then(resp => {
164 | res.status(200).json(resp);
165 | console.log(resp);
166 | return resp;
167 | })
168 | });
169 |
170 | //shortlist an application by id
171 | router.post("/shortlist_an_application",(req,res) => {
172 | var id = req.body.id;
173 | var query = { _id: id };
174 | var set = { $set: { status: "shortlisted" } };
175 | Application.updateMany(query , set , function(err , resp){
176 | if (err) throw err;
177 | })
178 | .then(resp => {
179 | res.status(200).json(resp);
180 | console.log(resp);
181 | return resp;
182 | })
183 | });
184 |
185 | module.exports = router;
--------------------------------------------------------------------------------
/frontend/src/components/Common/rate_my_employee.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import axios from 'axios';
3 | import PropTypes from 'prop-types';
4 | import Button from 'react-bootstrap/esm/Button';
5 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
6 |
7 |
8 | export default class Rate_applicant extends Component {
9 |
10 | constructor(props) {
11 | super(props);
12 |
13 | this.state = {
14 | applied_jobs:[],
15 | job:[],
16 | currentjob:[],
17 | idid:'',
18 | value:0,
19 | sop:'',
20 | lololol:false,
21 | status:'not applied',
22 | applicant_data:null,
23 | rating:5,
24 | }
25 | // this.apply_job = this.apply_job.bind(this);
26 | this.onChangerating = this.onChangerating.bind(this);
27 | this.onSubmit = this.onSubmit.bind(this);
28 | }
29 |
30 | onChangerating(event){
31 | this.setState({rating: event.target.rating});
32 | }
33 |
34 | componentDidMount(){
35 | console.log("ko")
36 | const chunk = {
37 | email: this.props.match.params.id,
38 | // applicant_email: localStorage.getItem("user_email"),
39 | // recruiter_email:
40 | }
41 | console.log(this.props.match.params)
42 | console.log(chunk)
43 | axios.post('http://localhost:4000/router/opop',chunk) //this is unused
44 | .then(res => {
45 | console.log("jii")
46 | var temper = 0;
47 |
48 | })
49 | .catch(err => {
50 | console.log(err);
51 | });
52 |
53 | }
54 |
55 | async onSubmit(e){
56 | e.preventDefault();
57 | console.log(this.props.match.params.id)
58 | const chunk = {
59 | id: this.props.match.params.id
60 | }
61 |
62 | var veer = true;
63 |
64 | {
65 |
66 |
67 |
68 |
69 | const yoyo = {
70 |
71 | email : this.props.match.params.id,
72 | value : this.state.rating
73 | }
74 | console.log(yoyo);
75 |
76 | var temp = {
77 | applicant_ka_email : this.props.match.params.id,
78 | }
79 |
80 | await axios.post('http://localhost:4000/Applicant/get_an_applicant_by_email', temp) //no such route found
81 | .then(res => {
82 | console.log(res.data);
83 | var ratecount = res.data.rate_count
84 | var rate = res.data.rating
85 | var newrating = (rate*ratecount+this.state.rating)/(ratecount+1)
86 | ratecount+=1
87 | var doupdate = {
88 | email:this.props.match.params.id,
89 | rate_count:ratecount,
90 | rating:newrating
91 | }
92 | this.setState({
93 | rating:newrating
94 | });
95 | axios.post('http://localhost:4000/Applicant/rate_an_applicant', doupdate) //no such route found
96 | .then(res => {
97 | console.log(res.data);
98 | // this.setState({jobs: res.data});
99 |
100 | })
101 | .catch(err =>
102 | {
103 | // if(err.response.data.message)
104 | // alert(err.response.data.message);
105 | console.log(err)
106 | });
107 | // this.setState({jobs: res.data});
108 |
109 | })
110 | .catch(err =>
111 | {
112 | // if(err.response.data.message)
113 | // alert(err.response.data.message);
114 | console.log(err)
115 | });
116 |
117 |
118 |
119 |
120 |
121 |
122 | // this.setState({
123 | // rating:newrating
124 | // });
125 | this.props.history.push('/job-listings');
126 | }
127 | }
128 |
129 | // apply_job(e){
130 | // const datadata = {
131 | // applicant_email: localStorage.getItem('user_email'),
132 | // recruiter_email: this.state.job.email_recruiter,
133 | // job_id: this.props.match.params.id,
134 |
135 | // }
136 | // const u = this.props.match.params.yoyo;
137 | // console.log(u)
138 | // }
139 |
140 | // componentDidMount() {
141 | // const u = this.props.match.params.yoyo;
142 | // console.log(u)
143 | // }
144 |
145 | render() {
146 |
147 | return (
148 |
149 |
150 | {/* {
151 | const kaha_jana = {
152 | pathname: "/search_job"
153 | }
154 | } */}
155 |
173 |
177 |
178 | )
179 |
180 |
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/backend/routes/Jobs.js:
--------------------------------------------------------------------------------
1 | var express = require("express");
2 | var router = express.Router();
3 | const Job = require("../models/Jobs");
4 |
5 | router.get("/s", function(req, res) {
6 | res.send("API is working properly !");
7 | });
8 | // get all jobs
9 | router.get("/jobs", function(req, res) {
10 | Job.find(function(err, Jobs) {
11 | if (err) {
12 | console.log(err);
13 | } else {
14 | res.json(Jobs);
15 | }
16 | })
17 | });
18 |
19 | // find all the non-deleted jobs for applicant
20 | router.get("/job/view_for_applicant",(req,res) => {
21 | var email = req.body.email_rec;
22 | Job.find({status:"present" , deadline_of_application: { $gt : Date.now() } })
23 | .then(resp => {
24 | res.status(200).json(resp);
25 | console.log(resp);
26 | return resp;
27 | })
28 | .catch(resp =>{
29 | res.status(400).json(err);
30 | console.log(err);
31 | return err;
32 | });
33 | });
34 |
35 | // find all job from perticular recruiter
36 | router.post("/job/search",(req,res) => {
37 | var job_ka_title = req.body.job_title;
38 | Job.find({status:"present", title: job_ka_title })
39 | .then(resp => {
40 | res.status(200).json(resp);
41 | console.log(resp);
42 | return resp;
43 | })
44 | .catch(resp => {
45 | res.status(400).json(err);
46 | console.log(err);
47 | return err;
48 | });
49 | });
50 |
51 | //find all the jobs of perticular duration
52 | router.post("/job/filterbyduration",(req,res) => {
53 | var job_ka_duration = req.body.job_duration;
54 | console.log(res.body)
55 | Job.find({status:"present", duration: { $lt: job_ka_duration} })
56 | .then(resp => {
57 | res.status(200).json(resp);
58 | console.log(resp);
59 | return resp;
60 | })
61 | .catch(resp => {
62 | res.status(400).json(err);
63 | console.log(err);
64 | return err;
65 | });
66 | });
67 |
68 | // find all job of perticular job type (job type filter)
69 | router.post("/job_type_filter",(req,res) => {
70 | var job_ka_type = req.body.job_ka_type;
71 | Job.find({status:"present", type_of_job: job_ka_type })
72 | .then(resp => {
73 | res.status(200).json(resp);
74 | console.log(resp);
75 | return resp;
76 | })
77 | .catch(resp => {
78 | res.status(400).json(err);
79 | console.log(err);
80 | return err;
81 | });
82 | });
83 |
84 | // find all job of between a range of salary (job salary filter)
85 | router.post("/salaryfilter",(req,res) => {
86 | var minimumsalary = req.body.min;
87 | var maximumsalary = req.body.max;
88 | Job.find({status:"present", salary_per_month: { $gte: minimumsalary, $lte: maximumsalary }})
89 | .then(resp => {
90 | res.status(200).json(resp);
91 | console.log(resp);
92 | return resp;
93 | })
94 | .catch(resp => {
95 | res.status(400).json(err);
96 | console.log(err);
97 | return err;
98 | });
99 | });
100 |
101 | // find all job from perticular recruiter
102 | router.post("/job/view",(req,res) => {
103 | var email = req.body.email_rec;
104 | Job.find({email_recruiter: email , status:"present" , deadline_of_application : { $gt : Date.now() } })
105 | .then(resp => {
106 | res.status(200).json(resp);
107 | console.log(resp);
108 | return resp;
109 | })
110 | });
111 |
112 | // delete a job by recruiter
113 | router.post("/job/delete",(req,res) => {
114 | var id = req.body.id;
115 | var query = { _id: id };
116 | var set = { $set: { status: "deleted" } };
117 | Job.updateMany(query , set , function(err , resp){
118 | if (err) throw err;
119 | })
120 | .then(resp => {
121 | res.status(200).json(resp);
122 | console.log(resp);
123 | return resp;
124 | })
125 | });
126 |
127 | // get a job by id
128 | router.post("/get_a_job_by_id",(req,res) => {
129 | var id = req.body.id;
130 | var query = { _id: id };
131 | Job.findOne(query, function(err , resp){
132 | if (err) throw err;
133 | })
134 | .then(resp => {
135 | res.status(200).json(resp);
136 | console.log(resp);
137 | return resp;
138 | })
139 | });
140 |
141 | // Add a job
142 | router.post('/job/add', (req, res) => {
143 | console.log(req);
144 | Job.findOne({email_recruiter : req.body.email_recruiter , title:req.body.title})
145 | .then(jobb =>{
146 | let job = new Job({
147 | title: req.body.title,
148 | max_applications: req.body.max_applications,
149 | max_positions: req.body.max_positions,
150 | deadline_of_application: req.body.deadline_of_application,
151 | required_skills: req.body.required_skills,
152 | type_of_job: req.body.type_of_job,
153 | duration: req.body.duration,
154 | salary_per_month: req.body.salary_per_month,
155 | name_recruiter: req.body.name_recruiter,
156 | email_recruiter: req.body.email_recruiter,
157 | date_of_posting: Date.now(),
158 | status: "present"
159 | });
160 | console.log(job);
161 | job.save()
162 | .then(job => {
163 | res.status(200).json(job);
164 | })
165 | .catch(err => {
166 | console.log(err);
167 | res.status(400).send(err);
168 | });
169 | })
170 | });
171 |
172 | // Add a job
173 | router.post('/job/edit', (req, res) => {
174 | console.log(req);
175 | Job.findOne({email_recruiter : req.body.email_recruiter , title:req.body.title})
176 | .then(jobb =>{
177 | var query = {email_recruiter:req.body.email_recruiter , title:req.body.title};
178 | var set = { $set:{
179 | // title: req.body.title,
180 | max_applications: req.body.max_applications,
181 | max_positions: req.body.max_positions,
182 | deadline_of_application: req.body.deadline_of_application,
183 | required_skills: req.body.required_skills,
184 | type_of_job: req.body.type_of_job,
185 | duration: req.body.duration,
186 | salary_per_month: req.body.salary_per_month,
187 | name_recruiter: req.body.name_recruiter,
188 | email_recruiter: req.body.email_recruiter,
189 | // date_of_posting: Date.now(),
190 | status: "present"
191 | }}
192 | Job.updateOne(query , set, function(err, resp){
193 | if (err) throw err;
194 | })
195 | .then(resp => {
196 | res.status(200).json(resp);
197 | console.log(resp);
198 | return resp;
199 | });
200 | })
201 | });
202 | module.exports = router;
--------------------------------------------------------------------------------
/frontend/src/components/Users/UsersList.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import Paper from '@material-ui/core/Paper';
4 | import Grid from '@material-ui/core/Grid';
5 | import TableCell from '@material-ui/core/TableCell';
6 | import TableHead from '@material-ui/core/TableHead';
7 | import TableRow from '@material-ui/core/TableRow';
8 | import Table from '@material-ui/core/Table';
9 | import TableBody from '@material-ui/core/TableBody';
10 | import Button from '@material-ui/core/Button';
11 | import TextField from '@material-ui/core/TextField';
12 | import List from '@material-ui/core/List';
13 | import ListItem from '@material-ui/core/ListItem';
14 | import Divider from '@material-ui/core/Divider';
15 | import Autocomplete from '@material-ui/lab/Autocomplete';
16 | import IconButton from "@material-ui/core/IconButton";
17 | import InputAdornment from "@material-ui/core/InputAdornment";
18 |
19 | import SearchIcon from "@material-ui/icons/Search";
20 | import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
21 | import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
22 |
23 |
24 | class UsersList extends Component {
25 |
26 | constructor(props) {
27 | super(props);
28 | this.state = {users: [],sortedUsers: [], sortName:true};
29 | this.renderIcon = this.renderIcon.bind(this);
30 | this.sortChange = this.sortChange.bind(this);
31 | }
32 |
33 | componentDidMount() {
34 | axios.get('http://localhost:4000/user/user')
35 | .then(response => {
36 | this.setState({users: response.data, sortedUsers:response.data});
37 | })
38 | .catch(function(error) {
39 | console.log(error);
40 | })
41 | }
42 |
43 | sortChange(){
44 | /**
45 | * Note that this is sorting only at front-end.
46 | */
47 | var array = this.state.users;
48 | var flag = this.state.sortName;
49 | array.sort(function(a, b) {
50 | if(a.date != undefined && b.date != undefined){
51 | return (1 - flag*2) * (new Date(a.date) - new Date(b.date));
52 | }
53 | else{
54 | return 1;
55 | }
56 | });
57 | this.setState({
58 | users:array,
59 | sortName:!this.state.sortName,
60 | })
61 | }
62 |
63 | renderIcon(){
64 | if(this.state.sortName){
65 | return(
66 |
67 | )
68 | }
69 | else{
70 | return(
71 |
72 | )
73 | }
74 | }
75 |
76 | render() {
77 | return (
78 |
79 |
80 |
81 |
82 |
83 | Filters
84 |
85 |
86 |
87 |
88 |
89 |
96 |
97 |
98 |
99 |
100 | )}}
101 | />
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
115 |
116 |
117 |
118 | option.name}
122 | style={{ width: 300 }}
123 | renderInput={(params) => }
124 | />
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | Date
134 | Name
135 | Email
136 |
137 |
138 |
139 | {this.state.users.map((user,ind) => (
140 |
141 | {user.date}
142 | {user.name}
143 | {user.email}
144 |
145 | ))}
146 |
147 |
148 |
149 |
150 |
151 |
152 | )
153 | }
154 | }
155 |
156 | export default UsersList;
--------------------------------------------------------------------------------
/frontend/src/components/Common/Profileedit_recruiter.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import React, {Component} from 'react';
4 | // import axios from 'axios';
5 | import bcrypt from 'bcryptjs';
6 | // import TextField from 'material-ui/TextField';
7 | // import getMuiTheme from 'material-ui/styles/getMuiTheme'
8 | // import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
9 | // import Paper from 'material-ui/Paper';
10 | import CssBaseline from '@material-ui/core/CssBaseline';
11 | import Avatar from '@material-ui/core/Avatar';
12 | import Container from '@material-ui/core/Container';
13 | import Typography from '@material-ui/core/Typography';
14 | import Button from '@material-ui/core/Button';
15 |
16 |
17 | export default class Profileedit_recruiter extends React.Component {
18 |
19 | constructor(props) {
20 | super(props);
21 |
22 | this.state = {
23 |
24 | bio:'',
25 | contact_number:'',
26 | name:''
27 | }
28 | // this.onChangetitle = this.onChangetitle.bind(this);
29 | // this.onChangemax_applications = this.onChangemax_applications.bind(this);
30 | // this.onChangemax_positions = this.onChangemax_positions.bind(this);
31 | // this.onChangedeadline_of_application = this.onChangedeadline_of_application.bind(this);
32 | // this.onChangerequired_skills = this.onChangerequired_skills.bind(this);
33 | // this.onChangetype_of_job = this.onChangetype_of_job.bind(this);
34 | // this.onChangeduration = this.onChangeduration.bind(this);
35 | // this.onChangesalary_per_month = this.onChangesalary_per_month.bind(this);
36 | this.onSubmit = this.onSubmit.bind(this);
37 | this.onChangebio = this.onChangebio.bind(this);
38 | this.onChangecontact_number = this.onChangecontact_number.bind(this);
39 | this.onChangename = this.onChangename.bind(this);
40 | }
41 |
42 | onChangebio(event) {
43 | this.setState({ bio: event.target.value });
44 | }
45 |
46 | onChangecontact_number(event) {
47 | this.setState({ contact_number: event.target.value });
48 | }
49 |
50 | onChangename(event){
51 | this.setState({name : event.target.value});
52 | }
53 |
54 | // onChangemax_positions(event) {
55 | // this.setState({ max_positions: event.target.value });
56 | // }
57 |
58 | // onChangedeadline_of_application(event) {
59 | // this.setState({ deadline_of_application: event.target.value });
60 | // }
61 |
62 | // onChangerequired_skills(event) {
63 | // this.setState({ required_skills: event.target.value });
64 | // }
65 |
66 | // onChangetype_of_job(event) {
67 | // this.setState({ type_of_job: event.target.value });
68 | // }
69 |
70 | // onChangeduration(event) {
71 | // this.setState({ duration: event.target.value });
72 | // }
73 |
74 | // onChangesalary_per_month(event) {
75 | // this.setState({ salary_per_month: event.target.value });
76 | // }
77 | componentDidMount()
78 | {
79 | console.log(localStorage)
80 | var mail=localStorage.getItem("user_email")
81 | console.log(mail)
82 | axios.post('http://localhost:4000/recruiter/get_a_recruiter_by_email',{"email":mail})
83 | .then(res => {this.setState({user:res.data})
84 | console.log(this.state.user)
85 | this.setState({name:this.state.user.name})
86 | this.setState({email:this.state.user.email})
87 | this.setState({bio:this.state.user.bio})
88 | this.setState({contact_number:this.state.user.contact_number})
89 | })
90 | };
91 |
92 | onSubmit(e) {
93 | e.preventDefault();
94 |
95 | const newrec = {
96 | // title: this.state.title,
97 | // max_applications: this.state.max_applications,
98 | // max_positions: this.state.max_positions,
99 | // deadline_of_application: Date(this.state.deadline_of_application),
100 | // required_skills: this.state.required_skills,
101 | // type_of_job: this.state.type_of_job,
102 | // duration: this.state.duration,
103 | // salary_per_month: this.state.salary_per_month,
104 | // name_recruiter: localStorage.getItem('user_name'),
105 | // email_recruiter: localStorage.getItem('user_email'),
106 | // date_of_posting: Date.now()
107 | bio: this.state.bio,
108 | contact_number: this.state.contact_number,
109 | email : localStorage.getItem("user_email"),
110 | name: this.state.name,
111 | }
112 |
113 | // console.log(newJob);
114 | console.log(localStorage.getItem('user_type'));
115 | console.log(localStorage.getItem('isloggedin'));
116 | if(localStorage.getItem('user_type') !== 'recruiter' || localStorage.getItem('isloggedin') !== 'true'){
117 | alert("please login first");
118 | this.props.history.push("/");
119 | window.location.reload();
120 | }
121 | else{
122 | if(this.state.contact_number.length === 10 && this.state.bio.split(' ').length < 251){
123 | axios.post('http://localhost:4000/recruiter/edit_recruiter_profile',newrec)
124 | .then(res => {
125 | alert("profile successfully edited");
126 | console.log(res.data)
127 | })
128 | .catch(function(error) {
129 | console.log(error);
130 | })
131 | axios.post('http://localhost:4000/user/updateuser',newrec)
132 | .then(res => {
133 |
134 | console.log(res.data)
135 | localStorage.setItem('user_name', this.state.name);
136 | console.log(localStorage)
137 | })
138 | .catch(function(error) {
139 | console.log(error);
140 | })
141 | }
142 | else{
143 | alert("number format is wrong or bio is too big (keep it under 251 words)")
144 | }
145 | }
146 | this.setState({
147 | // title: '',
148 | // name_recrutier: '',
149 | // email_recruiter: '',
150 | // max_applications: '',
151 | // max_positions: '',
152 | // deadline_of_application: '',
153 | // required_skills: '',
154 | // type_of_job: 'full_time',
155 | // duration: '0',
156 | // salary_per_month: '',
157 | // date_of_posting: Date.now()
158 | bio: '',
159 | contact_number: '',
160 | name:'',
161 | });
162 | }
163 |
164 | render() {
165 | return (
166 |
167 |
you can edit your profile here
168 |
208 |
209 | )
210 | }
211 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/Edit-job.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import React, {Component} from 'react';
4 | // import axios from 'axios';
5 | import bcrypt from 'bcryptjs';
6 | // import TextField from 'material-ui/TextField';
7 | // import getMuiTheme from 'material-ui/styles/getMuiTheme'
8 | // import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
9 | // import Paper from 'material-ui/Paper';
10 | import CssBaseline from '@material-ui/core/CssBaseline';
11 | import Avatar from '@material-ui/core/Avatar';
12 | import Container from '@material-ui/core/Container';
13 | import Typography from '@material-ui/core/Typography';
14 | import Button from '@material-ui/core/Button';
15 |
16 |
17 | export default class Edit_job extends React.Component {
18 |
19 | constructor(props) {
20 | super(props);
21 |
22 | this.state = {
23 | title: '',
24 | name_recrutier: '',
25 | email_recruiter: '',
26 | max_applications: '',
27 | max_positions: '',
28 | deadline_of_application: '',
29 | required_skills: '',
30 | type_of_job: 'full_time',
31 | duration: '0',
32 | salary_per_month: '',
33 | date_of_posting: Date.now()
34 | }
35 | this.onChangetitle = this.onChangetitle.bind(this);
36 | this.onChangemax_applications = this.onChangemax_applications.bind(this);
37 | this.onChangemax_positions = this.onChangemax_positions.bind(this);
38 | this.onChangedeadline_of_application = this.onChangedeadline_of_application.bind(this);
39 | this.onChangerequired_skills = this.onChangerequired_skills.bind(this);
40 | this.onChangetype_of_job = this.onChangetype_of_job.bind(this);
41 | this.onChangeduration = this.onChangeduration.bind(this);
42 | this.onChangesalary_per_month = this.onChangesalary_per_month.bind(this);
43 | this.onSubmit = this.onSubmit.bind(this);
44 | }
45 |
46 | onChangetitle(event) {
47 | this.setState({ title: event.target.value });
48 | }
49 |
50 | onChangemax_applications(event) {
51 | this.setState({ max_applications: event.target.value });
52 | }
53 |
54 | onChangemax_positions(event) {
55 | this.setState({ max_positions: event.target.value });
56 | }
57 |
58 | onChangedeadline_of_application(event) {
59 | this.setState({ deadline_of_application: event.target.value });
60 | }
61 |
62 | onChangerequired_skills(event) {
63 | this.setState({ required_skills: event.target.value });
64 | }
65 |
66 | onChangetype_of_job(event) {
67 | this.setState({ type_of_job: event.target.value });
68 | }
69 |
70 | onChangeduration(event) {
71 | this.setState({ duration: event.target.value });
72 | }
73 |
74 | onChangesalary_per_month(event) {
75 | this.setState({ salary_per_month: event.target.value });
76 | }
77 |
78 | onSubmit(e) {
79 | e.preventDefault();
80 |
81 | const newJob = {
82 | title: this.state.title,
83 | max_applications: this.state.max_applications,
84 | max_positions: this.state.max_positions,
85 | deadline_of_application: Date(this.state.deadline_of_application),
86 | required_skills: this.state.required_skills,
87 | type_of_job: this.state.type_of_job,
88 | duration: this.state.duration,
89 | salary_per_month: this.state.salary_per_month,
90 | name_recruiter: localStorage.getItem('user_name'),
91 | email_recruiter: localStorage.getItem('user_email'),
92 | date_of_posting: Date.now()
93 | }
94 |
95 | console.log(newJob);
96 | console.log(localStorage.getItem('user_type'));
97 | console.log(localStorage.getItem('isloggedin'));
98 | if(localStorage.getItem('user_type') !== 'recruiter' || localStorage.getItem('isloggedin') !== 'true'){
99 | alert("please login first");
100 | this.props.history.push("/");
101 | window.location.reload();
102 | }
103 | else{
104 | axios.post('http://localhost:4000/job/job/edit',newJob)
105 | .then(res => {
106 | alert("job successfully edited");
107 | console.log(res.data)
108 | })
109 | .catch(function(error) {
110 | console.log(error);
111 | })
112 | }
113 | this.setState({
114 | title: '',
115 | name_recrutier: '',
116 | email_recruiter: '',
117 | max_applications: '',
118 | max_positions: '',
119 | deadline_of_application: '',
120 | required_skills: '',
121 | type_of_job: 'full_time',
122 | duration: '0',
123 | salary_per_month: '',
124 | date_of_posting: Date.now()
125 | });
126 | }
127 |
128 | render() {
129 | return (
130 |
207 | )
208 | }
209 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/Add_jobs.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import bcrypt from 'bcryptjs';
4 | import CssBaseline from '@material-ui/core/CssBaseline';
5 | import Avatar from '@material-ui/core/Avatar';
6 | import Container from '@material-ui/core/Container';
7 | import Typography from '@material-ui/core/Typography';
8 | import Button from '@material-ui/core/Button';
9 |
10 |
11 | export default class Add_job extends React.Component {
12 |
13 | constructor(props) {
14 | super(props);
15 |
16 | this.state = {
17 | title: '',
18 | name_recrutier: '',
19 | email_recruiter: '',
20 | max_applications: '',
21 | max_positions: '',
22 | deadline_of_application: '',
23 | required_skills: '',
24 | type_of_job: 'full_time',
25 | duration: '0',
26 | salary_per_month: '',
27 | date_of_posting: Date.now()
28 | }
29 | this.onChangetitle = this.onChangetitle.bind(this);
30 | this.onChangemax_applications = this.onChangemax_applications.bind(this);
31 | this.onChangemax_positions = this.onChangemax_positions.bind(this);
32 | this.onChangedeadline_of_application = this.onChangedeadline_of_application.bind(this);
33 | this.onChangerequired_skills = this.onChangerequired_skills.bind(this);
34 | this.onChangetype_of_job = this.onChangetype_of_job.bind(this);
35 | this.onChangeduration = this.onChangeduration.bind(this);
36 | this.onChangesalary_per_month = this.onChangesalary_per_month.bind(this);
37 | this.onSubmit = this.onSubmit.bind(this);
38 | }
39 |
40 | onChangetitle(event) {
41 | this.setState({ title: event.target.value });
42 | }
43 |
44 | onChangemax_applications(event) {
45 | this.setState({ max_applications: event.target.value });
46 | }
47 |
48 | onChangemax_positions(event) {
49 | this.setState({ max_positions: event.target.value });
50 | }
51 |
52 | onChangedeadline_of_application(event) {
53 | this.setState({ deadline_of_application: event.target.value });
54 | }
55 |
56 | onChangerequired_skills(event) {
57 | this.setState({ required_skills: event.target.value });
58 | }
59 |
60 | onChangetype_of_job(event) {
61 | this.setState({ type_of_job: event.target.value });
62 | }
63 |
64 | onChangeduration(event) {
65 | this.setState({ duration: event.target.value });
66 | }
67 |
68 | onChangesalary_per_month(event) {
69 | this.setState({ salary_per_month: event.target.value });
70 | }
71 |
72 | onSubmit(e) {
73 | e.preventDefault();
74 |
75 | const newJob = {
76 | title: this.state.title,
77 | max_applications: this.state.max_applications,
78 | max_positions: this.state.max_positions,
79 | deadline_of_application: (this.state.deadline_of_application),
80 | required_skills: this.state.required_skills,
81 | type_of_job: this.state.type_of_job,
82 | duration: this.state.duration,
83 | salary_per_month: this.state.salary_per_month,
84 | name_recruiter: localStorage.getItem('user_name'),
85 | email_recruiter: localStorage.getItem('user_email'),
86 | date_of_posting: Date.now()
87 | }
88 |
89 | console.log(newJob);
90 | console.log(localStorage.getItem('user_type'));
91 | console.log(localStorage.getItem('isloggedin'));
92 | if(localStorage.getItem('user_type') !== 'recruiter' || localStorage.getItem('isloggedin') !== 'true'){
93 | alert("please login first");
94 | this.props.history.push("/");
95 | window.location.reload();
96 | }
97 | else{
98 | axios.post('http://localhost:4000/job/job/add',newJob)
99 | .then(res => {
100 | alert("job successfully added");
101 | console.log(res.data)
102 | })
103 | .catch(function(error) {
104 | console.log(error);
105 | })
106 | }
107 | this.setState({
108 | title: '',
109 | name_recrutier: '',
110 | email_recruiter: '',
111 | max_applications: '',
112 | max_positions: '',
113 | deadline_of_application: '',
114 | required_skills: '',
115 | type_of_job: 'full_time',
116 | duration: '0',
117 | salary_per_month: '',
118 | date_of_posting: Date.now()
119 | });
120 | }
121 |
122 | render() {
123 | return (
124 |
210 | )
211 | }
212 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/Job_info.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import axios from 'axios';
3 | import PropTypes from 'prop-types';
4 | import Button from 'react-bootstrap/esm/Button';
5 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
6 |
7 |
8 | export default class Job_info extends Component {
9 |
10 | constructor(props) {
11 | super(props);
12 |
13 | this.state = {
14 | applied_jobs:[],
15 | job:[],
16 | currentjob:[],
17 | idid:'',
18 | value:0,
19 | sop:'',
20 | lololol:false,
21 | status:'not applied',
22 | applicant_data:null,
23 | }
24 | // this.apply_job = this.apply_job.bind(this);
25 | this.onChangesop = this.onChangesop.bind(this);
26 | this.onSubmit = this.onSubmit.bind(this);
27 | }
28 |
29 | onChangesop(event){
30 | this.setState({sop: event.target.value});
31 | }
32 |
33 | componentDidMount(){
34 | if(localStorage.getItem('user_type') !== "applicant" && localStorage.getItem("isloggedin") !== true){
35 | alert("please log in");
36 | }
37 | else{
38 | console.log("ko")
39 | const chunk = {
40 | id: this.props.match.params.id,
41 | applicant_email: localStorage.getItem("user_email"),
42 | // recruiter_email:
43 | }
44 | console.log(chunk.id)
45 | axios.post('http://localhost:4000/application/app_p_or_n',{id: this.props.match.params.id})
46 | .then(res => {
47 | console.log("jii")
48 | var temper = 0;
49 | // for(var i = 0 ; i {
67 | console.log(err);
68 | });
69 | axios.post('http://localhost:4000/job/get_a_job_by_id', chunk)
70 | .then(res => {
71 | console.log(res.data);
72 | this.setState({job: res.data});
73 |
74 | this.setState({lololol: true});
75 | })
76 | .catch(err =>
77 | {
78 | // if(err.response.data.message)
79 | // alert(err.response.data.message);
80 | console.log(err)
81 | });
82 |
83 | // getting the data of this applicant
84 | const applicant_ka_data = {
85 | applicant_ka_email: localStorage.getItem("user_email")
86 | }
87 | axios.post('http://localhost:4000/applicant/get_an_applicant_by_email', applicant_ka_data)
88 | .then(res => {
89 | console.log(res.data);
90 | this.setState({applicant_data: res.data});
91 |
92 | this.setState({lololol: true});
93 | })
94 | .catch(err =>
95 | {
96 | // if(err.response.data.message)
97 | // alert(err.response.data.message);
98 | console.log(err)
99 | });
100 | }
101 | }
102 |
103 | async onSubmit(e){
104 | e.preventDefault();
105 | console.log(this.props.match.params.id)
106 | const chunk = {
107 | id: this.props.match.params.id
108 | }
109 |
110 | // console.log(temper)
111 | // if(temper === 0){
112 |
113 | // axios.post('http://localhost:4000/router/get_a_job_by_id', chunk)
114 | // .then(res => {
115 | // console.log(res.data);
116 | // this.setState({job: res.data});
117 |
118 | // this.setState({lololol: true});
119 | // })
120 | // .catch(err =>
121 | // {
122 | // // if(err.response.data.message)
123 | // // alert(err.response.data.message);
124 | // console.log(err)
125 | // });
126 | var veer = true;
127 |
128 | if(this.state.sop.split(' ').length>250){
129 | window.alert("word limit crossed");
130 | veer = false;
131 | }
132 | else if(veer && this.state.sop === ''){
133 | window.alert("enter statement of purpose");
134 | }
135 | else if(this.state.applicant_data.application_count >20){
136 | alert("max application limit reached");
137 | }
138 | else{
139 |
140 |
141 |
142 |
143 | const yoyo = {
144 | sop: this.state.sop,
145 | email_recruiter: this.state.job.email_recruiter,
146 | name_recruiter: this.state.job.name_recruiter,
147 | deadline_of_application: this.state.job.deadline_of_application,
148 | job_salary_per_month: this.state.job.salary_per_month,
149 | status_of_job:this.state.job.status,
150 | job_id: this.state.job._id,
151 | applicant_email: localStorage.getItem("user_email"),
152 | status: "applied",
153 | job_title: this.state.job.title,
154 | name_applicant:localStorage.getItem("user_name"),
155 | skills: this.state.applicant_data.list_of_languages,
156 | education: this.state.applicant_data.education,
157 | job_type:this.state.job.type_of_job,
158 | rating: this.state.applicant_data.rating,
159 | }
160 | console.log(yoyo);
161 | await axios.post('http://localhost:4000/application/addapplication', yoyo)
162 | .then(res => {
163 | console.log(res.data);
164 | // this.setState({jobs: res.data});
165 |
166 | })
167 | .catch(err =>
168 | {
169 | console.log(err)
170 | });
171 |
172 |
173 | await axios.post('http://localhost:4000/applicant/increment_application_count', {email: localStorage.getItem("user_email")})
174 | .then(res => {
175 | console.log(res.data);
176 | // this.setState({jobs: res.data});
177 |
178 | })
179 | .catch(err =>
180 | {
181 |
182 | console.log(err)
183 | });
184 |
185 | this.setState({
186 | sop:''
187 | });
188 | this.props.history.push('/search_job');
189 | }
190 | }
191 |
192 | // apply_job(e){
193 | // const datadata = {
194 | // applicant_email: localStorage.getItem('user_email'),
195 | // recruiter_email: this.state.job.email_recruiter,
196 | // job_id: this.props.match.params.id,
197 |
198 | // }
199 | // const u = this.props.match.params.yoyo;
200 | // console.log(u)
201 | // }
202 |
203 | // componentDidMount() {
204 | // const u = this.props.match.params.yoyo;
205 | // console.log(u)
206 | // }
207 |
208 | render() {
209 |
210 | return (
211 |
212 |
213 | {/* {
214 | const kaha_jana = {
215 | pathname: "/search_job"
216 | }
217 | } */}
218 |
232 |
236 |
237 | )
238 |
239 |
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/frontend/src/components/Common/my_employees.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import "bootstrap/dist/css/bootstrap.min.css";
4 | import Button from 'react-bootstrap/Button'
5 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
6 | export default class My_employees extends Component {
7 |
8 | constructor(props) {
9 | super(props);
10 | // this.deletejob = this.deletejob.bind(this)
11 | this.state = {
12 | listings: []
13 | }
14 | this.sortbynamedec = this.sortbynamedec.bind(this);
15 | this.sortbynameinc = this.sortbynameinc.bind(this);
16 | this.sortbydojdec = this.sortbydojdec.bind(this);
17 | this.sortbydojinc = this.sortbydojinc.bind(this);
18 | this.sortbyratingdec = this.sortbyratingdec.bind(this);
19 | this.sortbyratinginc = this.sortbyratinginc.bind(this);
20 | this.sortbytitledec = this.sortbytitledec.bind(this);
21 | this.sortbytitleinc = this.sortbytitleinc.bind(this);
22 | }
23 |
24 | componentDidMount() {
25 | if(localStorage.getItem('user_type') === "recruiter" && localStorage.getItem('isloggedin') === "true" ){
26 | let email = localStorage.getItem('user_email');
27 | const data_rec = {
28 | email_rec: email
29 | };
30 | axios.post('http://localhost:4000/application/all_my_employees', data_rec)
31 | .then(response => {
32 | console.log(response.data)
33 | this.setState({listings: response.data});
34 | })
35 | .catch(function(error) {
36 | // if(error.response.data.message)
37 | // alert(error.response.data.message);
38 | console.log(error);
39 | })
40 | }
41 | else{
42 | alert("login first");
43 | this.props.history.push("/");
44 | window.location.reload();
45 | }
46 | }
47 |
48 |
49 | rate_applicant(id) {
50 |
51 | }
52 |
53 | rate_applicant = this.rate_applicant;
54 |
55 | sortbynamedec = () => {
56 | let listings = this.state.listings, n = listings.length;
57 | for(var i =0; i < n-1; i++)
58 | {
59 | for(var j=0; j < n-1; j++)
60 | {
61 | var x = listings[j].name_applicant;
62 | var y = listings[j+1].name_applicant;
63 | if(x < y)
64 | {
65 | var temper = listings[j];
66 | listings[j] = listings[j+1];
67 | listings[j+1] = temper;
68 | }
69 | }
70 | }
71 | this.setState({listings: listings});
72 | }
73 |
74 | sortbynameinc = () => {
75 | let listings = this.state.listings, n = listings.length;
76 | for(var i =0; i < n-1; i++)
77 | {
78 | for(var j=0; j < n-1; j++)
79 | {
80 | var x = listings[j].name_applicant;
81 | var y = listings[j+1].name_applicant;
82 | if(x > y)
83 | {
84 | var temper = listings[j];
85 | listings[j] = listings[j+1];
86 | listings[j+1] = temper;
87 | }
88 | }
89 | }
90 | this.setState({listings: listings});
91 | }
92 |
93 | sortbytitledec = () => {
94 | let listings = this.state.listings, n = listings.length;
95 | for(var i =0; i < n-1; i++)
96 | {
97 | for(var j=0; j < n-1; j++)
98 | {
99 | var x = listings[j].job_title;
100 | var y = listings[j+1].job_title;
101 | if(x < y)
102 | {
103 | var temper = listings[j];
104 | listings[j] = listings[j+1];
105 | listings[j+1] = temper;
106 | }
107 | }
108 | }
109 | this.setState({listings: listings});
110 | }
111 |
112 | sortbytitleinc = () => {
113 | let listings = this.state.listings, n = listings.length;
114 | for(var i =0; i < n-1; i++)
115 | {
116 | for(var j=0; j < n-1; j++)
117 | {
118 | var x = listings[j].job_title;
119 | var y = listings[j+1].job_title;
120 | if(x > y)
121 | {
122 | var temper = listings[j];
123 | listings[j] = listings[j+1];
124 | listings[j+1] = temper;
125 | }
126 | }
127 | }
128 | this.setState({listings: listings});
129 | }
130 |
131 | sortbydojdec = () => {
132 | let listings = this.state.listings, n = listings.length;
133 | for(var i =0; i < n-1; i++)
134 | {
135 | for(var j=0; j < n-1; j++)
136 | {
137 | var x = (listings[j].date_of_joining);
138 | var y = (listings[j+1].date_of_joining);
139 | // var d1 = x.getTime();
140 | // let d2 = y.getTime();
141 | if(x {
153 | let listings = this.state.listings, n = listings.length;
154 | for(var i =0; i < n-1; i++)
155 | {
156 | for(var j=0; j < n-1; j++)
157 | {
158 | var x = listings[j].date_of_joining;
159 | var y = listings[j+1].date_of_joining;
160 | if(x > y)
161 | {
162 | var temper = listings[j];
163 | listings[j] = listings[j+1];
164 | listings[j+1] = temper;
165 | }
166 | }
167 | }
168 | this.setState({listings: listings});
169 | }
170 |
171 | sortbyratingdec = () => {
172 | let listings = this.state.listings, n = listings.length;
173 | for(var i =0; i < n-1; i++)
174 | {
175 | for(var j=0; j < n-1; j++)
176 | {
177 | var x = listings[j].applicant_rating;
178 | var y = listings[j+1].applicant_rating;
179 | if(x < y)
180 | {
181 | var temper = listings[j];
182 | listings[j] = listings[j+1];
183 | listings[j+1] = temper;
184 | }
185 | }
186 | }
187 | this.setState({listings: listings});
188 | }
189 |
190 | sortbyratinginc = () => {
191 | let listings = this.state.listings, n = listings.length;
192 | for(var i =0; i < n-1; i++)
193 | {
194 | for(var j=0; j < n-1; j++)
195 | {
196 | var x = listings[j].applicant_rating;
197 | var y = listings[j+1].applicant_rating;
198 | if(x > y)
199 | {
200 | var temper = listings[j];
201 | listings[j] = listings[j+1];
202 | listings[j+1] = temper;
203 | }
204 | }
205 | }
206 | this.setState({listings: listings});
207 | }
208 |
209 | render() {
210 | return (
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 | | applicant name |
224 | date of joining |
225 | job type |
226 | job title |
227 | {/* date of posting | */}
228 | applicant's rating |
229 | rate |
230 |
231 |
232 |
233 | {
234 | this.state.listings.map((application, i) => {
235 | const kaha_jana = {
236 | pathname: "/my-employees/"+application.applicant_email,
237 | }
238 | var vivi = null;
239 | // if(application.status === "accepted"){
240 | vivi = |
241 | // }
242 | return (
243 |
244 | | {application.name_applicant} |
245 | {application.date_of_joining} |
246 | {application.job_type} |
247 | {application.job_title} |
248 | {/* {application.date_of_joining} | */}
249 | {application.applicant_rating} |
250 | {/* | */}
251 | {vivi}
252 |
253 | )
254 | })
255 | }
256 |
257 |
258 |
259 | )
260 | }
261 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/Profileedit_applicant.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import Card from '@material-ui/core/Card'
4 | // import React, {Component} from 'react';
5 | // import axios from 'axios';
6 | import bcrypt from 'bcryptjs';
7 | // import TextField from 'material-ui/TextField';
8 | // import getMuiTheme from 'material-ui/styles/getMuiTheme'
9 | // import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
10 | // import Paper from 'material-ui/Paper';
11 | import CssBaseline from '@material-ui/core/CssBaseline';
12 | import Avatar from '@material-ui/core/Avatar';
13 | import Container from '@material-ui/core/Container';
14 | import Typography from '@material-ui/core/Typography';
15 | import Button from '@material-ui/core/Button';
16 |
17 | var cardStyle = {
18 | display: 'disk',
19 | width: '15vw',
20 | transitionDuration: '0.3s',
21 | height: '20vw'
22 | }
23 |
24 | export default class Profileedit_recruiter extends React.Component {
25 |
26 | constructor(props) {
27 | super(props);
28 |
29 | this.state = {
30 |
31 | list_of_languages:'',
32 | education: [],
33 | institution:'',
34 | startyear:'',
35 | endyear:'',
36 | image:'',
37 | cv:'',
38 | // contact_number:'',
39 | name:''
40 | }
41 |
42 | this.onSubmit = this.onSubmit.bind(this);
43 | this.onChangelist_of_languages = this.onChangelist_of_languages.bind(this);
44 | this.onChangeimage = this.onChangeimage.bind(this);
45 | this.onChangecv = this.onChangecv.bind(this);
46 | this.onChangeinstitution = this.onChangeinstitution.bind(this);
47 | this.onChangestartyear = this.onChangestartyear.bind(this);
48 | this.onChangeendyear = this.onChangeendyear.bind(this);
49 | this.onSubmitEdu = this.onSubmitEdu.bind(this);
50 | this.onChangename = this.onChangename.bind(this);
51 | }
52 |
53 | onChangelist_of_languages(event) {
54 | this.setState({ list_of_languages: event.target.value });
55 | }
56 |
57 | onChangeimage(event) {
58 | this.setState({ image: event.target.files[0] });
59 | const formData = new FormData();
60 | formData.append('file', event.target.files[0]);
61 | axios.post('http://localhost:4000/applicant/addfile?type=image&email=' + localStorage.getItem('user_email'), formData)
62 | .then(res => {
63 | console.log(res.json);
64 | })
65 | .catch(err => {
66 | console.log(err);
67 | });
68 | }
69 |
70 | onChangecv(event){
71 | this.setState({cv : event.target.value});
72 | const formData = new FormData();
73 | formData.append('file', event.target.files[0]);
74 | axios.post('http://localhost:4000/applicant/addfile?type=cv&email=' + localStorage.getItem('user_email'), formData)
75 | .then(res => {
76 | console.log(res.json);
77 | })
78 | .catch(err => {
79 | console.log(err);
80 | });
81 | }
82 |
83 | onChangestartyear(event){
84 | this.setState({startyear : event.target.value});
85 |
86 | }
87 |
88 | onChangeinstitution(event){
89 | this.setState({institution : event.target.value});
90 | }
91 |
92 | onChangeendyear(event){
93 | this.setState({endyear : event.target.value});
94 | }
95 |
96 | onChangename(event){
97 | this.setState({name: event.target.value});
98 | }
99 | componentDidMount()
100 | {
101 | console.log(localStorage)
102 | var mail=localStorage.getItem("user_email")
103 | console.log(mail)
104 | axios.post('http://localhost:4000/applicant/get_an_applicant_by_email',{"applicant_ka_email":mail})
105 | .then(res => {this.setState({user:res.data})
106 | console.log(this.state.user)
107 | this.setState({name:this.state.user.name})
108 | this.setState({email:this.state.user.email})
109 | this.setState({education:this.state.user.education})
110 | this.setState({list_of_languages:this.state.user.list_of_languages})
111 |
112 |
113 | })
114 |
115 | };
116 |
117 | onSubmit(e) {
118 | e.preventDefault();
119 | console.log("lol")
120 | const newrec = {
121 |
122 | list_of_languages:this.state.list_of_languages,
123 | education: this.state.education,
124 | email: localStorage.getItem('user_email'),
125 | image:this.state.image,
126 | cv:this.state.cv,
127 | // contact_number:'',
128 | name:this.state.name
129 | }
130 |
131 | // console.log(newJob);
132 | console.log(localStorage.getItem('user_type'));
133 | console.log(localStorage.getItem('isloggedin'));
134 | if(localStorage.getItem('user_type') !== 'applicant' || localStorage.getItem('isloggedin') !== 'true'){
135 | alert("please login first");
136 | this.props.history.push("/");
137 | window.location.reload();
138 | }
139 | else{
140 | console.log(newrec);
141 | // if(this.state.contact_number.length === 10 && this.state.bio.split(' ').length < 251){
142 | axios.post('http://localhost:4000/applicant/edit_applicant_profile',newrec)
143 | .then(res => {
144 | alert("profile successfully edited");
145 | console.log(res.data)
146 |
147 | })
148 | .catch(function(error) {
149 | console.log(error);
150 | });
151 | axios.post('http://localhost:4000/user/updateuser',newrec)
152 | .then(res => {
153 |
154 | console.log(res.data)
155 | localStorage.setItem('user_name', this.state.name);
156 | console.log(localStorage)
157 | })
158 | .catch(function(error) {
159 | console.log(error);
160 | })
161 |
162 | // if(newrec.image != ''){
163 | // axios.post('http://localhost:4000/applicant/addfile?type=image&email=' + newrec.email, newrec.image )
164 | // .then(res => {
165 | // console.log(res.json);
166 | // })
167 | // .catch(err => {
168 | // console.log(err);
169 | // })
170 | // }
171 | // }
172 | // else{
173 | // alert("number format is wrong or bio is too big (keep it under 251 words)")
174 | // }
175 | }
176 | this.setState({
177 |
178 | list_of_languages:'',
179 | education: [],
180 | institution:'',
181 | startyear:'',
182 | endyear:'',
183 | image:'',
184 | cv:'',
185 | // contact_number:'',
186 | name:''
187 | });
188 | }
189 |
190 |
191 |
192 | onSubmitEdu(e){
193 | e.preventDefault();
194 | const obj = {
195 | institution: this.state.institution,
196 | startyear: this.state.startyear,
197 | endyear: this.state.endyear
198 | }
199 |
200 | if(this.state.institution === '' || this.state.startyear === ''){
201 | alert("you cannot leave institution and startyear feild empty.")
202 | }
203 | else{
204 | let e1 = this.state.education;
205 | e1.push(obj);
206 | this.setState({
207 | education: e1,
208 | institution: '',
209 | startyear: '',
210 | endyear: ''
211 | });
212 | }
213 |
214 | }
215 |
216 | render() {
217 | return (
218 |
219 |
220 |
221 |
222 |
223 |
224 |
229 |
230 |
235 |
289 |
290 |
291 |
292 |
293 |
294 | )
295 | }
296 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/job_application_info_rec.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import axios from 'axios';
3 | import PropTypes from 'prop-types';
4 | import Button from 'react-bootstrap/esm/Button';
5 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
6 |
7 |
8 | export default class Job_application_info extends Component {
9 |
10 | constructor(props) {
11 | super(props);
12 |
13 | this.state = {
14 | applied_jobs:[],
15 | applications:[],
16 | currentjob:[],
17 | idid:'',
18 | value:0,
19 | sop:'',
20 | lololol:false,
21 | status:'not applied'
22 | }
23 | this.sortbyratinginc = this.sortbyratinginc.bind(this);
24 | this.sortbyratingdec = this.sortbyratingdec.bind(this);
25 | this.sortbydoadec = this.sortbydoadec.bind(this);
26 | this.sortbydoainc = this.sortbydoainc.bind(this);
27 | this.sortbynamedec = this.sortbynamedec.bind(this);
28 | this.sortbynameinc = this.sortbynameinc.bind(this);
29 |
30 | this.shortlist = this.shortlist.bind(this);
31 | this.accept = this.accept.bind(this);
32 | this.reject = this.reject.bind(this);
33 | }
34 |
35 | onChangesop(event){
36 | this.setState({sop: event.target.value});
37 | }
38 |
39 | componentDidMount(){
40 | if(localStorage.getItem('user_type') !== "recruiter" && localStorage.getItem("isloggedin") !== true){
41 | alert("please log in");
42 | }
43 | else{
44 | console.log("ko")
45 | const chunk = {
46 | id: this.props.match.params.id,
47 | email_recruiter: localStorage.getItem("user_email"),
48 | }
49 | console.log(chunk.id)
50 | axios.post('http://localhost:4000/application/all_my_non-rejected_applications_of_perticular_job',chunk)
51 | .then(res => {
52 | console.log(res.data)
53 | var temper = 0;
54 | this.setState({applications: res.data});
55 | })
56 | .catch(err => {
57 | console.log(err);
58 | });
59 | }
60 | }
61 |
62 | async reject(id , mail ){
63 | axios.post('http://localhost:4000/application/reject_an_application',{id:id})
64 | .then(res => {
65 | console.log(res.data)
66 | })
67 | .catch(err => {
68 | console.log(err);
69 | });
70 | axios.post('http://localhost:4000/application/decrement_application_count', {email: mail})
71 | .then(res => {
72 | console.log(res.data);
73 | })
74 | .catch(err =>
75 | {
76 | console.log(err)
77 | });
78 | window.location.reload();
79 | }
80 |
81 | accept(id){
82 | axios.post('http://localhost:4000/application/accept_an_application',{id:id })
83 | .then(res => {
84 | console.log(res.data)
85 | })
86 | .catch(err => {
87 | console.log(err);
88 | });
89 | window.location.reload();
90 | }
91 |
92 | shortlist(id){
93 | axios.post('http://localhost:4000/application/shortlist_an_application',{id:id})
94 | .then(res => {
95 | console.log(res.data)
96 | })
97 | .catch(err => {
98 | console.log(err);
99 | });
100 | window.location.reload();
101 | }
102 |
103 | async onSubmit(e){
104 | e.preventDefault();
105 | console.log(this.props.match.params.id)
106 | const chunk = {
107 | id: this.props.match.params.id
108 | }
109 | var veer = true;
110 |
111 | // if(this.state.sop.split(' ').length>250){
112 | // window.alert("word limit crossed");
113 | // veer = false;
114 | // }
115 | // else if(veer && this.state.sop === ''){
116 | // window.alert("enter statement of purpose");
117 | // }
118 | // else{
119 | // const yoyo = {
120 | // sop: this.state.sop,
121 | // email_recruiter: this.state.job.email_recruiter,
122 | // name_recruiter: this.state.job.name_recruiter,
123 | // deadline_of_application: this.state.job.deadline_of_application,
124 | // job_salary_per_month: this.state.job.salary_per_month,
125 | // status_of_job:this.state.job.status,
126 | // job_id: this.state.job._id,
127 | // applicant_email: localStorage.getItem("user_email"),
128 | // status: "applied",
129 | // job_title: this.state.job.title
130 | // }
131 | // console.log(yoyo);
132 | // await axios.post('http://localhost:4000/router/addapplication', yoyo)
133 | // .then(res => {
134 | // console.log(res.data);
135 | // // this.setState({jobs: res.data});
136 |
137 | // })
138 | // .catch(err =>
139 | // {
140 | // // if(err.response.data.message)
141 | // // alert(err.response.data.message);
142 | // console.log(err)
143 | // });
144 |
145 | // this.setState({
146 | // sop:''
147 | // });
148 | // this.props.history.push('/search_job');
149 | // }
150 | }
151 |
152 | // apply_job(e){
153 | // const datadata = {
154 | // applicant_email: localStorage.getItem('user_email'),
155 | // recruiter_email: this.state.job.email_recruiter,
156 | // job_id: this.props.match.params.id,
157 |
158 | // }
159 | // const u = this.props.match.params.yoyo;
160 | // console.log(u)
161 | // }
162 |
163 | // componentDidMount() {
164 | // const u = this.props.match.params.yoyo;
165 | // console.log(u)
166 | // }
167 |
168 | sortbydoadec = () => {
169 | let applications = this.state.applications, n = applications.length;
170 | for(var i =0; i < n-1; i++)
171 | {
172 | for(var j=0; j < n-1; j++)
173 | {
174 | var x = applications[j].date_of_application;
175 | var y = applications[j+1].date_of_application;
176 | if(x < y)
177 | {
178 | var temper = applications[j];
179 | applications[j] = applications[j+1];
180 | applications[j+1] = temper;
181 | }
182 | }
183 | }
184 | this.setState({applications: applications});
185 | }
186 |
187 | sortbydoainc = () => {
188 | let applications = this.state.applications, n = applications.length;
189 | for(var i =0; i < n-1; i++)
190 | {
191 | for(var j=0; j < n-1; j++)
192 | {
193 | var x = applications[j].date_of_application;
194 | var y = applications[j+1].date_of_application;
195 | if(x > y)
196 | {
197 | var temper = applications[j];
198 | applications[j] = applications[j+1];
199 | applications[j+1] = temper;
200 | }
201 | }
202 | }
203 | this.setState({applications: applications});
204 | }
205 |
206 | sortbynamedec = () => {
207 | let applications = this.state.applications, n = applications.length;
208 | for(var i =0; i < n-1; i++)
209 | {
210 | for(var j=0; j < n-1; j++)
211 | {
212 | var x = applications[j].name_applicant;
213 | var y = applications[j+1].name_applicant;
214 | if(x < y)
215 | {
216 | var temper = applications[j];
217 | applications[j] = applications[j+1];
218 | applications[j+1] = temper;
219 | }
220 | }
221 | }
222 | this.setState({applications: applications});
223 | }
224 |
225 | sortbynameinc = () => {
226 | let applications = this.state.applications, n = applications.length;
227 | for(var i =0; i < n-1; i++)
228 | {
229 | for(var j=0; j < n-1; j++)
230 | {
231 | var x = applications[j].name_applicant;
232 | var y = applications[j+1].name_applicant;
233 | if(x > y)
234 | {
235 | var temper = applications[j];
236 | applications[j] = applications[j+1];
237 | applications[j+1] = temper;
238 | }
239 | }
240 | }
241 | this.setState({applications: applications});
242 | }
243 |
244 | sortbyratingdec = () =>{
245 | let applications = this.state.applications, n = applications.length;
246 | for(var i =0; i < n-1; i++)
247 | {
248 | for(var j=0; j < n-1; j++)
249 | {
250 | var x = applications[j].applicant_rating;
251 | var y = applications[j+1].applicant_rating;
252 | if(x < y)
253 | {
254 | var temper = applications[j];
255 | applications[j] = applications[j+1];
256 | applications[j+1] = temper;
257 | }
258 | }
259 | }
260 | this.setState({applications: applications});
261 | }
262 |
263 | sortbyratinginc = () =>{
264 | let applications = this.state.applications, n = applications.length;
265 | for(var i =0; i < n-1; i++)
266 | {
267 | for(var j=0; j < n-1; j++)
268 | {
269 | var x = applications[j].applicant_rating;
270 | var y = applications[j+1].applicant_rating;
271 | if(x > y)
272 | {
273 | var temper = applications[j];
274 | applications[j] = applications[j+1];
275 | applications[j+1] = temper;
276 | }
277 | }
278 | }
279 | this.setState({applications: applications});
280 | }
281 |
282 | render() {
283 | return (
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 | | applicant's name |
295 | skills of applicant |
296 | date of application |
297 | education |
298 | statement of purpose |
299 | stage of application |
300 |
301 |
302 |
303 | {
304 | this.state.applications.map((application, i) => {
305 | let divi = null;
306 | if(application.status === "applied"){
307 | divi =
308 |
309 |
|
310 | |
311 |
312 | }
313 | else if(application.status === "shortlisted"){
314 | divi =
315 |
316 |
|
317 | |
318 |
319 | }
320 | else if(application.status === "accepted"){
321 | divi =
322 |
323 |
|
324 |
325 | }
326 | var yoyo = null;
327 | {
328 | console.log(application.education_applicant)
329 | application.education_applicant.map((xx,j) => {
330 | var yoyoyo =
331 |
334 | })
335 | }
336 | return (
337 |
338 | | {application.name_applicant} |
339 | {application.skills_applicant} |
340 | {application.date_of_application} |
341 |
342 | {yoyo}
343 | |
344 | {application.sop} |
345 | {application.status} |
346 | {divi} |
347 |
348 | )
349 | })
350 | }
351 |
352 |
353 |
354 | )
355 | }
356 | }
357 |
--------------------------------------------------------------------------------
/frontend/src/components/Common/Register.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | import bcrypt from 'bcryptjs';
4 | // import TextField from 'material-ui/TextField';
5 | // import getMuiTheme from 'material-ui/styles/getMuiTheme'
6 | // import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
7 | // import Paper from 'material-ui/Paper';
8 | import CssBaseline from '@material-ui/core/CssBaseline';
9 | import Avatar from '@material-ui/core/Avatar';
10 | import Container from '@material-ui/core/Container';
11 | import Typography from '@material-ui/core/Typography';
12 | import Button from '@material-ui/core/Button';
13 |
14 |
15 | export default class Register extends Component {
16 |
17 | constructor(props) {
18 | super(props);
19 |
20 | this.state = {
21 | name: '',
22 | email: '',
23 | password: '',
24 | confirmPassword: '',
25 | emailerrortext: '',
26 | confirmPasswordErrorText: '',
27 | type: 'applicant',
28 | date:null,
29 | bio_recruiter:'',
30 | contact_number:'',
31 | list_of_languages:'',
32 | education:[],
33 | institution:'',
34 | startyear:'',
35 | endyear:'',
36 | image:'',
37 | cv:'',
38 | success:0
39 | }
40 |
41 | this.onChangeUsername = this.onChangeUsername.bind(this);
42 | this.onChangeEmail = this.onChangeEmail.bind(this);
43 | this.onChangeConfirmPassword = this.onChangeConfirmPassword.bind(this);
44 | this.onChangePassword = this.onChangePassword.bind(this);
45 | this.onSubmit = this.onSubmit.bind(this);
46 | this.onChangetype = this.onChangetype.bind(this);
47 | this.onChangecontactnumber = this.onChangecontactnumber.bind(this);
48 | this.onChangebio_recruiter = this.onChangebio_recruiter.bind(this);
49 | this.onChangelist_of_languages = this.onChangelist_of_languages.bind(this);
50 |
51 | this.onChangeEndyear = this.onChangeEndyear.bind(this);
52 | this.onChangeInstitution = this.onChangeInstitution.bind(this);
53 | this.onChangeStartyear = this.onChangeStartyear.bind(this);
54 |
55 | this.onSubmitEdu = this.onSubmitEdu.bind(this);
56 |
57 | this.onChangeimage = this.onChangeimage.bind(this);
58 | this.onChangecv = this.onChangecv.bind(this);
59 | }
60 |
61 | validateEmail(e) {
62 | var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
63 | return re.test(e);
64 | }
65 |
66 | onChangeEmail(event){
67 | var errortext=''
68 | if(!this.validateEmail(event.target.value)){
69 | errortext="email not excepted"
70 | }
71 | this.setState({ emailerrortext: errortext , email: event.target.value })
72 | }
73 |
74 | onChangelist_of_languages(event){
75 | this.setState({list_of_languages: event.target.value});
76 | }
77 |
78 | onChangeUsername(event) {
79 | this.setState({ name: event.target.value });
80 | }
81 |
82 | onChangecontactnumber(event){
83 | this.setState({contact_number: event.target.value});
84 | }
85 |
86 | onChangebio_recruiter(event){
87 | this.setState({bio_recruiter: event.target.value});
88 | }
89 |
90 | onChangePassword(event){
91 | this.setState({ password: event.target.value });
92 | }
93 |
94 | onChangeStartyear(event){
95 | this.setState({startyear: event.target.value});
96 | }
97 |
98 | onChangeInstitution(event){
99 | this.setState({institution: event.target.value});
100 | }
101 |
102 | onChangeEndyear(event){
103 | this.setState({endyear: event.target.value});
104 | }
105 | onChangeConfirmPassword(event){
106 | var errortext = ''
107 | if(event.target.value != this.state.password){
108 | errortext = 'password are not matched'
109 | }
110 | this.state({ confirmPassword: event.target.value , confirmPasswordErrorText: errortext });
111 | }
112 |
113 | onChangetype(event){
114 | this.setState({ type: event.target.value });
115 | }
116 |
117 | onSubmit(event) {
118 | event.preventDefault();
119 | const userAdd = {
120 | email: this.state.email,
121 | password: this.state.password
122 | }
123 | console.log(userAdd)
124 | axios.get('http://localhost:4000/user/user', userAdd)
125 | .then(res => {
126 | var tmpflag = 0
127 | var temp = "none";
128 | console.log(res);
129 | for(var i=0;i=6)){
146 | const rounds = 1;
147 | console.log(this.state.password);
148 | const hash = bcrypt.hashSync(this.state.password,rounds);
149 | const newUser = {
150 | name: this.state.name,
151 | email: this.state.email,
152 | password: hash,
153 | type: this.state.type,
154 | date: Date.now(),
155 | bio_recruiter: this.state.bio_recruiter,
156 | contact_number: this.state.contact_number,
157 | list_of_languages: this.state.list_of_languages,
158 | education: this.state.education,
159 | cv: this.state.cv,
160 | image: this.state.image,
161 | }
162 | console.log(this.state.password);
163 | console.log(hash);
164 | console.log(newUser);
165 | if(this.state.type === "recruiter"){
166 | if(this.state.bio_recruiter.split(' ').length < 251 && this.state.contact_number.length === 10){
167 | console.log("lololol");
168 | axios.post('http://localhost:4000/recruiter/recruiter/add', newUser)
169 | .then(res => {alert("Created recruiter\t" + res.data.name);console.log(res.data)
170 | this.setState({success:1})
171 | console.log("sucess updated")
172 | })
173 | .catch(err => {
174 | console.log(err)
175 | });
176 | }
177 | else{
178 | alert("contact number length is short or bio is too long keep it under 250 words");
179 | }
180 | }
181 | else if(this.state.type === "applicant"){
182 | if(this.state.list_of_languages !== ''){
183 | axios.post('http://localhost:4000/applicant/applicant/add', newUser)
184 | .then(res => {alert("Created applicant\t" + res.data.name);console.log(res.data)
185 | this.setState({success:1})
186 | console.log("sucess updated")
187 | })
188 | .catch(err => {
189 | console.log(err)
190 | });
191 | }
192 | else{
193 | alert("fill all components");
194 | }
195 | }
196 | axios.post('http://localhost:4000/user/register', newUser)
197 | }
198 | else if(this.state.password.length<6){
199 | alert("password length should be atleast 6");console.log("short password");
200 | }
201 | else{
202 | alert("email format is wrong");console.log("email format is wrong");
203 | }
204 | this.setState({
205 | name: '',
206 | email: '',
207 | password: '',
208 | confirmPassword: '',
209 | // emailerrortext: '',
210 | // confirmPasswordErrorText: '',
211 | type: 'applicant',
212 | date:null,
213 | bio_recruiter:'',
214 | contact_number:'',
215 | list_of_languages:'',
216 | image:'',
217 | cv:'',
218 | education:[]
219 | });
220 | }
221 | })
222 | .catch(err => {
223 | console.log(err)
224 | });
225 | }
226 |
227 | onChangeimage = e => {
228 | const vivi = new FileReader();
229 | vivi.onload = function() {
230 | this.setState({ image: e.target.files[0] });
231 | }.bind(this);
232 | vivi.readAsDataURL(e.target.files[0]);
233 | };
234 |
235 | onChangecv = e => {
236 | const vivi = new FileReader();
237 | vivi.onload = function() {
238 | this.setState({ cv: vivi.result });
239 | }.bind(this);
240 | vivi.readAsDataURL(e.target.files[0]);
241 | };
242 |
243 | onSubmitEdu(e){
244 | e.preventDefault();
245 | const obj = {
246 | institution: this.state.institution,
247 | startyear: this.state.startyear,
248 | endyear: this.state.endyear
249 | }
250 |
251 | if(this.state.institution === '' || this.state.startyear === ''){
252 | alert("you cannot leave institution and startyear feild empty.")
253 | }
254 | else{
255 | let e1 = this.state.education;
256 | e1.push(obj);
257 | this.setState({
258 | education: e1,
259 | institution: '',
260 | startyear: '',
261 | endyear: ''
262 | });
263 | }
264 |
265 | }
266 |
267 | render() {
268 | let divi = null;
269 | if(this.state.type === "applicant"){
270 | divi =
271 |
272 |
273 |
274 |
279 |
330 |
331 |
332 |
333 | }
334 | else{
335 | divi =
336 |
354 | }
355 | return (
356 | this.state.success == 1 ? window.location.href='/login' :
357 |
358 |
359 |
360 | {/* */}
361 |
362 |
363 | {/* */}
364 |
365 |
411 |
412 | )
413 | }
414 | }
--------------------------------------------------------------------------------
/frontend/src/components/Common/View_job_listings_applicant.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import axios from 'axios';
3 | // import CustomerNavbar from "./user-navbar.component"
4 | import { BrowserRouter as Router, Route, Link} from "react-router-dom";
5 | import Button from 'react-bootstrap/Button'
6 |
7 |
8 | export default class View_job_listings_applicant extends Component {
9 |
10 | constructor(props) {
11 | super(props);
12 |
13 | this.state = {
14 | search: '',
15 | jobs: [],
16 | job_type: 'full_time',
17 | job_salary: '',
18 | job_duration: '',
19 | salary_lower:'',
20 | salary_upper:'',
21 | applied_jobs:[]
22 | }
23 | this.onChangeSearch = this.onChangeSearch.bind(this);
24 | this.sortbyratinginc = this.sortbyratinginc.bind(this);
25 | this.sortbyratingdec = this.sortbyratingdec.bind(this);
26 | this.sortbydurationdec = this.sortbydurationdec.bind(this);
27 | this.sortbydurationinc = this.sortbydurationinc.bind(this);
28 | this.onchangedurationfilter = this.onchangedurationfilter.bind(this);
29 | this.onSubmitdurationfilter = this.onSubmitdurationfilter.bind(this);
30 |
31 | this.sortbysalarydec = this.sortbysalarydec.bind(this);
32 | this.sortbysalaryinc = this.sortbysalaryinc.bind(this);
33 | this.onChangejobtypefilter = this.onChangejobtypefilter.bind(this);
34 | this.onSubmitjobtypefilter = this.onSubmitjobtypefilter.bind(this);
35 |
36 | this.onchangesalarylower = this.onchangesalarylower.bind(this);
37 | this.onchangesalaryupper = this.onchangesalaryupper.bind(this);
38 | this.onSubmitsalaryrange = this.onSubmitsalaryrange.bind(this);
39 | }
40 |
41 | componentDidMount() {
42 | if(localStorage.getItem('user_type') === "applicant" && localStorage.getItem('isloggedin') === "true" ){
43 | let email = localStorage.getItem('user_email');
44 | const data_rec = {
45 | email_rec: email
46 | };
47 | axios.get('http://localhost:4000/job/job/view_for_applicant', data_rec)
48 | .then(response => {
49 | console.log(response.data)
50 | this.setState({jobs: response.data});
51 | console.log(this.state.jobs);
52 | })
53 | .catch(function(error) {
54 | console.log(error);
55 | })
56 | const newval = {
57 | applicant_email: localStorage.getItem("user_email")
58 | }
59 | axios.post("http://localhost:4000/application/all_applied_jobs",newval)
60 | .then(response =>{
61 | this.setState({applied_jobs: response.data});
62 | })
63 | .catch(function(error) {
64 | window.alert("post error")
65 | })
66 | }
67 | else{
68 | alert("login first");
69 | console.log("lul");
70 | this.props.history.push("/");
71 | window.location.reload();
72 | }
73 | }
74 |
75 | onChangeSearch(event) {
76 | this.setState({ search: event.target.value });
77 | console.log(event.target.value)
78 | }
79 |
80 | onChangejobtypefilter(event){
81 | this.setState({job_type: event.target.value});
82 | }
83 |
84 | onChangeType(event) {
85 | this.setState({ type: event.target.value });
86 | }
87 |
88 | onchangesalarylower(event){
89 | this.setState({salary_lower:event.target.value});
90 | }
91 |
92 | onchangesalaryupper(event){
93 | this.setState({salary_upper:event.target.value});
94 | }
95 |
96 | onchangedurationfilter(event){
97 | this.setState({job_duration: event.target.value});
98 | }
99 |
100 | onSubmitsalaryrange(e){
101 | e.preventDefault();
102 | const salaryminmax = {
103 | min: this.state.salary_lower,
104 | max: this.state.salary_upper
105 | }
106 | console.log(salaryminmax);
107 | axios.post('http://localhost:4000/router/salaryfilter', salaryminmax)
108 | .then(res => {
109 | console.log(res.data);
110 | this.setState({jobs: res.data});
111 |
112 | })
113 | .catch(err =>
114 | {
115 | console.log(err)
116 | });
117 |
118 | this.setState({
119 | salary_lower : '',
120 | salary_upper: ''
121 | });
122 | }
123 |
124 | onSubmitjobtypefilter(e){
125 | e.preventDefault();
126 | console.log(this.state.job_type)
127 | const jobtypefilter = {
128 | job_ka_type: this.state.job_type
129 | }
130 | console.log(jobtypefilter);
131 | axios.post('http://localhost:4000/router/job_type_filter', jobtypefilter)
132 | .then(res => {
133 | console.log(res.data);
134 | this.setState({jobs: res.data});
135 |
136 | })
137 | .catch(err =>
138 | {
139 | console.log(err)
140 | });
141 |
142 | this.setState({
143 | job_type : 'full_time',
144 | });
145 |
146 | }
147 |
148 | onSubmitdurationfilter(e){
149 | e.preventDefault();
150 | const dur = {
151 | job_duration: this.state.job_duration,
152 | }
153 | console.log(dur);
154 | axios.post('http://localhost:4000/router/job/filterbyduration', dur)
155 | .then(res => {
156 | console.log(res.data);
157 | this.setState({jobs: res.data});
158 |
159 | })
160 | .catch(err =>
161 | {
162 | console.log(err)
163 | });
164 |
165 | this.setState({
166 | search : '',
167 | });
168 | }
169 |
170 | sortbydurationdec = () =>{
171 | let jobs = this.state.jobs, n = jobs.length;
172 | for(var i =0; i < n-1; i++)
173 | {
174 | for(var j=0; j < n-1; j++)
175 | {
176 | var x = jobs[j].duration;
177 | var y = jobs[j+1].duration;
178 | if(x < y)
179 | {
180 | var temper = jobs[j];
181 | jobs[j] = jobs[j+1];
182 | jobs[j+1] = temper;
183 | }
184 | }
185 | }
186 | this.setState({jobs: jobs});
187 | }
188 |
189 | sortbydurationinc = () =>{
190 | let jobs = this.state.jobs, n = jobs.length;
191 | for(var i =0; i < n-1; i++)
192 | {
193 | for(var j=0; j < n-1; j++)
194 | {
195 | var x = jobs[j].duration;
196 | var y = jobs[j+1].duration;
197 | if(x > y)
198 | {
199 | var temper = jobs[j];
200 | jobs[j] = jobs[j+1];
201 | jobs[j+1] = temper;
202 | }
203 | }
204 | }
205 | this.setState({jobs: jobs});
206 | }
207 |
208 | sortbyratingdec = () =>{
209 | let jobs = this.state.jobs, n = jobs.length;
210 | for(var i =0; i < n-1; i++)
211 | {
212 | for(var j=0; j < n-1; j++)
213 | {
214 | var x = jobs[j].rating;
215 | var y = jobs[j+1].rating;
216 | if(x < y)
217 | {
218 | var temper = jobs[j];
219 | jobs[j] = jobs[j+1];
220 | jobs[j+1] = temper;
221 | }
222 | }
223 | }
224 | this.setState({jobs: jobs});
225 | }
226 |
227 | sortbyratinginc = () =>{
228 | let jobs = this.state.jobs, n = jobs.length;
229 | for(var i =0; i < n-1; i++)
230 | {
231 | for(var j=0; j < n-1; j++)
232 | {
233 | var x = jobs[j].rating;
234 | var y = jobs[j+1].rating;
235 | if(x > y)
236 | {
237 | var temper = jobs[j];
238 | jobs[j] = jobs[j+1];
239 | jobs[j+1] = temper;
240 | }
241 | }
242 | }
243 | this.setState({jobs: jobs});
244 | }
245 |
246 | sortbysalarydec = () =>{
247 | let jobs = this.state.jobs, n = jobs.length;
248 | for(var i=0; i < n-1; i++)
249 | {
250 | for(var j=0; j < n-1; j++)
251 | {
252 | var x = jobs[j].salary_per_month;
253 | var y = jobs[j+1].salary_per_month;
254 | if(x < y)
255 | {
256 | var temper = jobs[j];
257 | jobs[j] = jobs[j+1];
258 | jobs[j+1] = temper;
259 | }
260 | }
261 | }
262 | this.setState({jobs: jobs});
263 | }
264 |
265 | sortbysalaryinc = () =>{
266 | let jobs = this.state.jobs, n = jobs.length;
267 | for(var i=0; i < n-1; i++)
268 | {
269 | for(var j=0; j < n-1; j++)
270 | {
271 | var x = jobs[j].salary_per_month;
272 | var y = jobs[j+1].salary_per_month;
273 | if(x > y)
274 | {
275 | var temper = jobs[j];
276 | jobs[j] = jobs[j+1];
277 | jobs[j+1] = temper;
278 | }
279 | }
280 | }
281 | this.setState({jobs: jobs});
282 | }
283 |
284 |
285 |
286 | render() {
287 | const { jobs} = this.state;
288 | return (
289 |
290 |
consider 0 in duration as indefinite.
291 | {/*
*/}
305 |
323 |
324 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 | | job title |
380 | salary |
381 | {/* positions left | */}
382 | recruiter |
383 | email of recruiter |
384 | Rating |
385 | duration |
386 | maximum applications |
387 | maximum positions |
388 | {/* number of positions filled | */}
389 | date of posting |
390 | deadline of application |
391 | required skills |
392 | type of job |
393 |
394 |
395 |
396 | {
397 |
398 | this.state.jobs.map((job, i) => {
399 | const kaha_jana = {
400 | pathname: "/job_apply/"+job._id,
401 | // job: job,
402 | // yoyo: "yoyo"
403 | }
404 | // console.log(i);
405 | var array=[...this.state.applied_jobs]
406 | let mark=false;
407 | // console.log(array.length)
408 | for(var j=0;jApplied
420 | }
421 | else{
422 | if(job.number_of_positions_filled >= job.max_applications + job.max_applications){
423 | www =
424 | }
425 | else{
426 | www =
427 |
433 | }
434 |
435 | }
436 | // console.log(i,mark)
437 | // console.log(job.status)
438 |
439 | let x = 0, rating =0;
440 |
441 | //rating = product
442 | const wow = new Date(Date.now());
443 | const wowow = new Date(job.deadline_of_application);
444 | if(job.title.includes(this.state.search) || this.state.search === '' ){
445 | return (
446 |
447 | | {job.title} |
448 | {job.salary_per_month} |
449 | {job.name_recruiter} |
450 | {job.email_recruiter} |
451 | {job.rating} |
452 | {job.duration} |
453 | {job.max_applications} |
454 | {job.max_positions} |
455 | {job.date_of_posting} |
456 | {job.deadline_of_application} |
457 | {job.required_skills} |
458 | {job.type_of_job} |
459 |
460 | {www} |
461 |
462 | )
463 | }
464 | })
465 | }
466 |
467 |
468 |
469 | )
470 | }
471 | }
--------------------------------------------------------------------------------