[
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# Next.js build output\n.next\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and *not* Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n© 2021 GitHub, Inc.\nTerms\nPrivacy\nSecurity\nStatus\nHelp\nContact GitHub\nPricing\nAPI\nTraining\nBlog\nAbout\nOctotree\n Login with GitHub\n\nbackend/public/profile/*\nbackend/public/resume/*"
  },
  {
    "path": "README.md",
    "content": "# Job Portal\r\n\r\nJob Portal is a MERN Stack based web app which helps in streamlining the flow of job application process. It allows users to select there roles (applicant/recruiter), and create an account. In this web app, login session are persistent and REST APIs are securely protected by JWT token verification. After logging in, a recruiter can create/delete/update jobs, shortlist/accept/reject applications, view resume and edit profile. And, an applicant can view jobs, perform fuzzy search with various filters, apply for jobs with an SOP, view applications, upload profile picture, upload resume and edit profile. Hence, it is an all in one solution for a job application system.\r\n\r\nDemo: [Click Here](https://www.youtube.com/watch?v=lIrN-LbbBnw&ab_channel=ShlokPandey)\r\n\r\nDirectory structure of the web app is as follows:\r\n\r\n```\r\n- backend/\r\n    - public/\r\n        - profile/\r\n        - resume/\r\n- frontend/\r\n- README.md\r\n```\r\n\r\n## Instructions for initializing web app:\r\n\r\n- Install Node JS, MongoDB in the machine.\r\n- Start MongoDB server: `sudo service mongod start`\r\n- Move inside backend directory: `cd backend`\r\n- Install dependencies in backend directory: `npm install`\r\n- Start express server: `npm start`\r\n- Backend server will start on port 4444.\r\n- Now go inside frontend directory: `cd ..\\frontend`\r\n- Install dependencies in frontend directory: `npm install`\r\n- Start web app's frontend server: `npm start`\r\n- Frontend server will start on port 3000.\r\n- Now open `http://localhost:3000/` and proceed creating jobs and applications by signing up in required categories.\r\n\r\n## Dependencies:\r\n\r\n- Frontend\r\n  - @material-ui/core\r\n  - @material-ui/icons\r\n  - @material-ui/lab\r\n  - axios\r\n  - material-ui-chip-input\r\n  - react-phone-input-2\r\n- Backend\r\n  - bcrypt\r\n  - body-parser\r\n  - connect-flash\r\n  - connect-mongo\r\n  - cors\r\n  - crypto\r\n  - express\r\n  - express-session\r\n  - jsonwebtoken\r\n  - mongoose\r\n  - mongoose-type-email\r\n  - multer\r\n  - passport\r\n  - passport-jwt\r\n  - passport-local\r\n  - uuid\r\n\r\n# Machine Specifications\r\n\r\nDetails of the machine on which the webapp was tested:\r\n\r\n- Operating System: Elementary OS 5.1 (Hera)\r\n- Terminal: Bash\r\n- Processor: Intel Core i7-8750H CPU @ 2.20 GHz 2.21 GHz\r\n- RAM: 16 GB\r\n"
  },
  {
    "path": "backend/db/Application.js",
    "content": "const mongoose = require(\"mongoose\");\n\nlet schema = new mongoose.Schema(\n  {\n    userId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    recruiterId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    jobId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    status: {\n      type: String,\n      enum: [\n        \"applied\", // when a applicant is applied\n        \"shortlisted\", // when a applicant is shortlisted\n        \"accepted\", // when a applicant is accepted\n        \"rejected\", // when a applicant is rejected\n        \"deleted\", // when any job is deleted\n        \"cancelled\", // an application is cancelled by its author or when other application is accepted\n        \"finished\", // when job is over\n      ],\n      default: \"applied\",\n      required: true,\n    },\n    dateOfApplication: {\n      type: Date,\n      default: Date.now,\n    },\n    dateOfJoining: {\n      type: Date,\n      validate: [\n        {\n          validator: function (value) {\n            return this.dateOfApplication <= value;\n          },\n          msg: \"dateOfJoining should be greater than dateOfApplication\",\n        },\n      ],\n    },\n    sop: {\n      type: String,\n      validate: {\n        validator: function (v) {\n          return v.split(\" \").filter((ele) => ele != \"\").length <= 250;\n        },\n        msg: \"Statement of purpose should not be greater than 250 words\",\n      },\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\n// schema.virtual(\"applicationUser\", {\n//   ref: \"JobApplicantInfo\",\n//   localField: \"userId\",\n//   foreignField: \"userId\",\n//   justOne: true,\n// });\n\n// schema.virtual(\"applicationRecruiter\", {\n//   ref: \"RecruiterInfo\",\n//   localField: \"recruiterId\",\n//   foreignField: \"userId\",\n//   justOne: true,\n// });\n\n// schema.virtual(\"applicationJob\", {\n//   ref: \"jobs\",\n//   localField: \"jobId\",\n//   foreignField: \"_id\",\n//   justOne: true,\n// });\n\nmodule.exports = mongoose.model(\"applications\", schema);\n"
  },
  {
    "path": "backend/db/Job.js",
    "content": "const mongoose = require(\"mongoose\");\n\nlet schema = new mongoose.Schema(\n  {\n    userId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    title: {\n      type: String,\n      required: true,\n    },\n    maxApplicants: {\n      type: Number,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"maxApplicants should be an integer\",\n        },\n        {\n          validator: function (value) {\n            return value > 0;\n          },\n          msg: \"maxApplicants should greater than 0\",\n        },\n      ],\n    },\n    maxPositions: {\n      type: Number,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"maxPostions should be an integer\",\n        },\n        {\n          validator: function (value) {\n            return value > 0;\n          },\n          msg: \"maxPositions should greater than 0\",\n        },\n      ],\n    },\n    activeApplications: {\n      type: Number,\n      default: 0,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"activeApplications should be an integer\",\n        },\n        {\n          validator: function (value) {\n            return value >= 0;\n          },\n          msg: \"activeApplications should greater than equal to 0\",\n        },\n      ],\n    },\n    acceptedCandidates: {\n      type: Number,\n      default: 0,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"acceptedCandidates should be an integer\",\n        },\n        {\n          validator: function (value) {\n            return value >= 0;\n          },\n          msg: \"acceptedCandidates should greater than equal to 0\",\n        },\n      ],\n    },\n    dateOfPosting: {\n      type: Date,\n      default: Date.now,\n    },\n    deadline: {\n      type: Date,\n      validate: [\n        {\n          validator: function (value) {\n            return this.dateOfPosting < value;\n          },\n          msg: \"deadline should be greater than dateOfPosting\",\n        },\n      ],\n    },\n    skillsets: [String],\n    jobType: {\n      type: String,\n      required: true,\n    },\n    duration: {\n      type: Number,\n      min: 0,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"Duration should be an integer\",\n        },\n      ],\n    },\n    salary: {\n      type: Number,\n      validate: [\n        {\n          validator: Number.isInteger,\n          msg: \"Salary should be an integer\",\n        },\n        {\n          validator: function (value) {\n            return value >= 0;\n          },\n          msg: \"Salary should be positive\",\n        },\n      ],\n    },\n    rating: {\n      type: Number,\n      max: 5.0,\n      default: -1.0,\n      validate: {\n        validator: function (v) {\n          return v >= -1.0 && v <= 5.0;\n        },\n        msg: \"Invalid rating\",\n      },\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\nmodule.exports = mongoose.model(\"jobs\", schema);\n"
  },
  {
    "path": "backend/db/JobApplicant.js",
    "content": "const mongoose = require(\"mongoose\");\n\nlet schema = new mongoose.Schema(\n  {\n    userId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    name: {\n      type: String,\n      required: true,\n    },\n    education: [\n      {\n        institutionName: {\n          type: String,\n          required: true,\n        },\n        startYear: {\n          type: Number,\n          min: 1930,\n          max: new Date().getFullYear(),\n          required: true,\n          validate: Number.isInteger,\n        },\n        endYear: {\n          type: Number,\n          max: new Date().getFullYear(),\n          validate: [\n            { validator: Number.isInteger, msg: \"Year should be an integer\" },\n            {\n              validator: function (value) {\n                return this.startYear <= value;\n              },\n              msg: \"End year should be greater than or equal to Start year\",\n            },\n          ],\n        },\n      },\n    ],\n    skills: [String],\n    rating: {\n      type: Number,\n      max: 5.0,\n      default: -1.0,\n      validate: {\n        validator: function (v) {\n          return v >= -1.0 && v <= 5.0;\n        },\n        msg: \"Invalid rating\",\n      },\n    },\n    resume: {\n      type: String,\n    },\n    profile: {\n      type: String,\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\nmodule.exports = mongoose.model(\"JobApplicantInfo\", schema);\n"
  },
  {
    "path": "backend/db/Rating.js",
    "content": "const mongoose = require(\"mongoose\");\n\nlet schema = new mongoose.Schema(\n  {\n    category: {\n      type: String,\n      enum: [\"job\", \"applicant\"],\n      required: true,\n    },\n    receiverId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    senderId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    rating: {\n      type: Number,\n      max: 5.0,\n      default: -1.0,\n      validate: {\n        validator: function (v) {\n          return v >= -1.0 && v <= 5.0;\n        },\n        msg: \"Invalid rating\",\n      },\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\nschema.index({ category: 1, receiverId: 1, senderId: 1 }, { unique: true });\n\nmodule.exports = mongoose.model(\"ratings\", schema);\n"
  },
  {
    "path": "backend/db/Recruiter.js",
    "content": "const mongoose = require(\"mongoose\");\n\nlet schema = new mongoose.Schema(\n  {\n    userId: {\n      type: mongoose.Schema.Types.ObjectId,\n      required: true,\n    },\n    name: {\n      type: String,\n      required: true,\n    },\n    contactNumber: {\n      type: String,\n      validate: {\n        validator: function (v) {\n          return v !== \"\" ? /\\+\\d{1,3}\\d{10}/.test(v) : true;\n        },\n        msg: \"Phone number is invalid!\",\n      },\n    },\n    bio: {\n      type: String,\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\nmodule.exports = mongoose.model(\"RecruiterInfo\", schema);\n"
  },
  {
    "path": "backend/db/User.js",
    "content": "const mongoose = require(\"mongoose\");\nconst bcrypt = require(\"bcrypt\");\nrequire(\"mongoose-type-email\");\n\nlet schema = new mongoose.Schema(\n  {\n    email: {\n      type: mongoose.SchemaTypes.Email,\n      unique: true,\n      lowercase: true,\n      required: true,\n    },\n    password: {\n      type: String,\n      required: true,\n    },\n    type: {\n      type: String,\n      enum: [\"recruiter\", \"applicant\"],\n      required: true,\n    },\n  },\n  { collation: { locale: \"en\" } }\n);\n\n// Password hashing\nschema.pre(\"save\", function (next) {\n  let user = this;\n\n  // if the data is not modified\n  if (!user.isModified(\"password\")) {\n    return next();\n  }\n\n  bcrypt.hash(user.password, 10, (err, hash) => {\n    if (err) {\n      return next(err);\n    }\n    user.password = hash;\n    next();\n  });\n});\n\n// Password verification upon login\nschema.methods.login = function (password) {\n  let user = this;\n\n  return new Promise((resolve, reject) => {\n    bcrypt.compare(password, user.password, (err, result) => {\n      if (err) {\n        reject(err);\n      }\n      if (result) {\n        resolve();\n      } else {\n        reject();\n      }\n    });\n  });\n};\n\nmodule.exports = mongoose.model(\"UserAuth\", schema);\n"
  },
  {
    "path": "backend/lib/authKeys.js",
    "content": "module.exports = {\n  jwtSecretKey: \"jwt_secret\",\n};\n"
  },
  {
    "path": "backend/lib/jwtAuth.js",
    "content": "const passport = require(\"passport\");\n\nconst jwtAuth = (req, res, next) => {\n  passport.authenticate(\"jwt\", { session: false }, function (err, user, info) {\n    if (err) {\n      return next(err);\n    }\n    if (!user) {\n      res.status(401).json(info);\n      return;\n    }\n    req.user = user;\n    next();\n  })(req, res, next);\n};\n\nmodule.exports = jwtAuth;\n"
  },
  {
    "path": "backend/lib/passportConfig.js",
    "content": "const passport = require(\"passport\");\nconst Strategy = require(\"passport-local\").Strategy;\n\nconst passportJWT = require(\"passport-jwt\");\nconst JWTStrategy = passportJWT.Strategy;\nconst ExtractJWT = passportJWT.ExtractJwt;\n\nconst User = require(\"../db/User\");\nconst authKeys = require(\"./authKeys\");\n\nconst filterJson = (obj, unwantedKeys) => {\n  const filteredObj = {};\n  Object.keys(obj).forEach((key) => {\n    if (unwantedKeys.indexOf(key) === -1) {\n      filteredObj[key] = obj[key];\n    }\n  });\n  return filteredObj;\n};\n\npassport.use(\n  new Strategy(\n    {\n      usernameField: \"email\",\n      passReqToCallback: true,\n    },\n    (req, email, password, done, res) => {\n      // console.log(email, password);\n      User.findOne({ email: email }, (err, user) => {\n        if (err) {\n          return done(err);\n        }\n        if (!user) {\n          return done(null, false, {\n            message: \"User does not exist\",\n          });\n        }\n\n        user\n          .login(password)\n          .then(() => {\n            // let userSecure = {};\n            // const unwantedKeys = [\"password\", \"__v\"];\n            // Object.keys(user[\"_doc\"]).forEach((key) => {\n            //   if (unwantedKeys.indexOf(key) === -1) {\n            //     userSecure[key] = user[key];\n            //   }\n            // });\n            user[\"_doc\"] = filterJson(user[\"_doc\"], [\"password\", \"__v\"]);\n            return done(null, user);\n          })\n          .catch((err) => {\n            return done(err, false, {\n              message: \"Password is incorrect.\",\n            });\n          });\n      });\n    }\n  )\n);\n\npassport.use(\n  new JWTStrategy(\n    {\n      jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken(),\n      secretOrKey: authKeys.jwtSecretKey,\n    },\n    (jwt_payload, done) => {\n      User.findById(jwt_payload._id)\n        .then((user) => {\n          console.log(Object.keys(jwt_payload));\n          if (!user) {\n            return done(null, false, {\n              message: \"JWT Token does not exist\",\n            });\n          }\n          user[\"_doc\"] = filterJson(user[\"_doc\"], [\"password\", \"__v\"]);\n          return done(null, user);\n        })\n        .catch((err) => {\n          return done(err, false, {\n            message: \"Incorrect Token\",\n          });\n        });\n    }\n  )\n);\n\nmodule.exports = passport;\n"
  },
  {
    "path": "backend/package.json",
    "content": "{\n  \"name\": \"job-portal-backend\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"start\": \"npx nodemon server.js\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"bcrypt\": \"^5.0.0\",\n    \"body-parser\": \"^1.19.0\",\n    \"connect-flash\": \"^0.1.1\",\n    \"connect-mongo\": \"^3.2.0\",\n    \"cors\": \"^2.8.5\",\n    \"crypto\": \"^1.0.1\",\n    \"express\": \"^4.17.1\",\n    \"express-session\": \"^1.17.1\",\n    \"jsonwebtoken\": \"^8.5.1\",\n    \"mongoose\": \"^5.11.11\",\n    \"mongoose-type-email\": \"^1.1.2\",\n    \"multer\": \"^2.0.0-rc.2\",\n    \"passport\": \"^0.4.1\",\n    \"passport-jwt\": \"^4.0.0\",\n    \"passport-local\": \"^1.0.0\",\n    \"uuid\": \"^8.3.2\"\n  }\n}\n"
  },
  {
    "path": "backend/routes/apiRoutes.js",
    "content": "const express = require(\"express\");\nconst mongoose = require(\"mongoose\");\nconst jwtAuth = require(\"../lib/jwtAuth\");\n\nconst User = require(\"../db/User\");\nconst JobApplicant = require(\"../db/JobApplicant\");\nconst Recruiter = require(\"../db/Recruiter\");\nconst Job = require(\"../db/Job\");\nconst Application = require(\"../db/Application\");\nconst Rating = require(\"../db/Rating\");\n\nconst router = express.Router();\n\n// To add new job\nrouter.post(\"/jobs\", jwtAuth, (req, res) => {\n  const user = req.user;\n\n  if (user.type != \"recruiter\") {\n    res.status(401).json({\n      message: \"You don't have permissions to add jobs\",\n    });\n    return;\n  }\n\n  const data = req.body;\n\n  let job = new Job({\n    userId: user._id,\n    title: data.title,\n    maxApplicants: data.maxApplicants,\n    maxPositions: data.maxPositions,\n    dateOfPosting: data.dateOfPosting,\n    deadline: data.deadline,\n    skillsets: data.skillsets,\n    jobType: data.jobType,\n    duration: data.duration,\n    salary: data.salary,\n    rating: data.rating,\n  });\n\n  job\n    .save()\n    .then(() => {\n      res.json({ message: \"Job added successfully to the database\" });\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// to get all the jobs [pagination] [for recruiter personal and for everyone]\nrouter.get(\"/jobs\", jwtAuth, (req, res) => {\n  let user = req.user;\n\n  let findParams = {};\n  let sortParams = {};\n\n  // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;\n  // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;\n  // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;\n\n  // to list down jobs posted by a particular recruiter\n  if (user.type === \"recruiter\" && req.query.myjobs) {\n    findParams = {\n      ...findParams,\n      userId: user._id,\n    };\n  }\n\n  if (req.query.q) {\n    findParams = {\n      ...findParams,\n      title: {\n        $regex: new RegExp(req.query.q, \"i\"),\n      },\n    };\n  }\n\n  if (req.query.jobType) {\n    let jobTypes = [];\n    if (Array.isArray(req.query.jobType)) {\n      jobTypes = req.query.jobType;\n    } else {\n      jobTypes = [req.query.jobType];\n    }\n    console.log(jobTypes);\n    findParams = {\n      ...findParams,\n      jobType: {\n        $in: jobTypes,\n      },\n    };\n  }\n\n  if (req.query.salaryMin && req.query.salaryMax) {\n    findParams = {\n      ...findParams,\n      $and: [\n        {\n          salary: {\n            $gte: parseInt(req.query.salaryMin),\n          },\n        },\n        {\n          salary: {\n            $lte: parseInt(req.query.salaryMax),\n          },\n        },\n      ],\n    };\n  } else if (req.query.salaryMin) {\n    findParams = {\n      ...findParams,\n      salary: {\n        $gte: parseInt(req.query.salaryMin),\n      },\n    };\n  } else if (req.query.salaryMax) {\n    findParams = {\n      ...findParams,\n      salary: {\n        $lte: parseInt(req.query.salaryMax),\n      },\n    };\n  }\n\n  if (req.query.duration) {\n    findParams = {\n      ...findParams,\n      duration: {\n        $lt: parseInt(req.query.duration),\n      },\n    };\n  }\n\n  if (req.query.asc) {\n    if (Array.isArray(req.query.asc)) {\n      req.query.asc.map((key) => {\n        sortParams = {\n          ...sortParams,\n          [key]: 1,\n        };\n      });\n    } else {\n      sortParams = {\n        ...sortParams,\n        [req.query.asc]: 1,\n      };\n    }\n  }\n\n  if (req.query.desc) {\n    if (Array.isArray(req.query.desc)) {\n      req.query.desc.map((key) => {\n        sortParams = {\n          ...sortParams,\n          [key]: -1,\n        };\n      });\n    } else {\n      sortParams = {\n        ...sortParams,\n        [req.query.desc]: -1,\n      };\n    }\n  }\n\n  console.log(findParams);\n  console.log(sortParams);\n\n  // Job.find(findParams).collation({ locale: \"en\" }).sort(sortParams);\n  // .skip(skip)\n  // .limit(limit)\n\n  let arr = [\n    {\n      $lookup: {\n        from: \"recruiterinfos\",\n        localField: \"userId\",\n        foreignField: \"userId\",\n        as: \"recruiter\",\n      },\n    },\n    { $unwind: \"$recruiter\" },\n    { $match: findParams },\n  ];\n\n  if (Object.keys(sortParams).length > 0) {\n    arr = [\n      {\n        $lookup: {\n          from: \"recruiterinfos\",\n          localField: \"userId\",\n          foreignField: \"userId\",\n          as: \"recruiter\",\n        },\n      },\n      { $unwind: \"$recruiter\" },\n      { $match: findParams },\n      {\n        $sort: sortParams,\n      },\n    ];\n  }\n\n  console.log(arr);\n\n  Job.aggregate(arr)\n    .then((posts) => {\n      if (posts == null) {\n        res.status(404).json({\n          message: \"No job found\",\n        });\n        return;\n      }\n      res.json(posts);\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// to get info about a particular job\nrouter.get(\"/jobs/:id\", jwtAuth, (req, res) => {\n  Job.findOne({ _id: req.params.id })\n    .then((job) => {\n      if (job == null) {\n        res.status(400).json({\n          message: \"Job does not exist\",\n        });\n        return;\n      }\n      res.json(job);\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// to update info of a particular job\nrouter.put(\"/jobs/:id\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type != \"recruiter\") {\n    res.status(401).json({\n      message: \"You don't have permissions to change the job details\",\n    });\n    return;\n  }\n  Job.findOne({\n    _id: req.params.id,\n    userId: user.id,\n  })\n    .then((job) => {\n      if (job == null) {\n        res.status(404).json({\n          message: \"Job does not exist\",\n        });\n        return;\n      }\n      const data = req.body;\n      if (data.maxApplicants) {\n        job.maxApplicants = data.maxApplicants;\n      }\n      if (data.maxPositions) {\n        job.maxPositions = data.maxPositions;\n      }\n      if (data.deadline) {\n        job.deadline = data.deadline;\n      }\n      job\n        .save()\n        .then(() => {\n          res.json({\n            message: \"Job details updated successfully\",\n          });\n        })\n        .catch((err) => {\n          res.status(400).json(err);\n        });\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// to delete a job\nrouter.delete(\"/jobs/:id\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type != \"recruiter\") {\n    res.status(401).json({\n      message: \"You don't have permissions to delete the job\",\n    });\n    return;\n  }\n  Job.findOneAndDelete({\n    _id: req.params.id,\n    userId: user.id,\n  })\n    .then((job) => {\n      if (job === null) {\n        res.status(401).json({\n          message: \"You don't have permissions to delete the job\",\n        });\n        return;\n      }\n      res.json({\n        message: \"Job deleted successfully\",\n      });\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// get user's personal details\nrouter.get(\"/user\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type === \"recruiter\") {\n    Recruiter.findOne({ userId: user._id })\n      .then((recruiter) => {\n        if (recruiter == null) {\n          res.status(404).json({\n            message: \"User does not exist\",\n          });\n          return;\n        }\n        res.json(recruiter);\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  } else {\n    JobApplicant.findOne({ userId: user._id })\n      .then((jobApplicant) => {\n        if (jobApplicant == null) {\n          res.status(404).json({\n            message: \"User does not exist\",\n          });\n          return;\n        }\n        res.json(jobApplicant);\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  }\n});\n\n// get user details from id\nrouter.get(\"/user/:id\", jwtAuth, (req, res) => {\n  User.findOne({ _id: req.params.id })\n    .then((userData) => {\n      if (userData === null) {\n        res.status(404).json({\n          message: \"User does not exist\",\n        });\n        return;\n      }\n\n      if (userData.type === \"recruiter\") {\n        Recruiter.findOne({ userId: userData._id })\n          .then((recruiter) => {\n            if (recruiter === null) {\n              res.status(404).json({\n                message: \"User does not exist\",\n              });\n              return;\n            }\n            res.json(recruiter);\n          })\n          .catch((err) => {\n            res.status(400).json(err);\n          });\n      } else {\n        JobApplicant.findOne({ userId: userData._id })\n          .then((jobApplicant) => {\n            if (jobApplicant === null) {\n              res.status(404).json({\n                message: \"User does not exist\",\n              });\n              return;\n            }\n            res.json(jobApplicant);\n          })\n          .catch((err) => {\n            res.status(400).json(err);\n          });\n      }\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// update user details\nrouter.put(\"/user\", jwtAuth, (req, res) => {\n  const user = req.user;\n  const data = req.body;\n  if (user.type == \"recruiter\") {\n    Recruiter.findOne({ userId: user._id })\n      .then((recruiter) => {\n        if (recruiter == null) {\n          res.status(404).json({\n            message: \"User does not exist\",\n          });\n          return;\n        }\n        if (data.name) {\n          recruiter.name = data.name;\n        }\n        if (data.contactNumber) {\n          recruiter.contactNumber = data.contactNumber;\n        }\n        if (data.bio) {\n          recruiter.bio = data.bio;\n        }\n        recruiter\n          .save()\n          .then(() => {\n            res.json({\n              message: \"User information updated successfully\",\n            });\n          })\n          .catch((err) => {\n            res.status(400).json(err);\n          });\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  } else {\n    JobApplicant.findOne({ userId: user._id })\n      .then((jobApplicant) => {\n        if (jobApplicant == null) {\n          res.status(404).json({\n            message: \"User does not exist\",\n          });\n          return;\n        }\n        if (data.name) {\n          jobApplicant.name = data.name;\n        }\n        if (data.education) {\n          jobApplicant.education = data.education;\n        }\n        if (data.skills) {\n          jobApplicant.skills = data.skills;\n        }\n        if (data.resume) {\n          jobApplicant.resume = data.resume;\n        }\n        if (data.profile) {\n          jobApplicant.profile = data.profile;\n        }\n        console.log(jobApplicant);\n        jobApplicant\n          .save()\n          .then(() => {\n            res.json({\n              message: \"User information updated successfully\",\n            });\n          })\n          .catch((err) => {\n            res.status(400).json(err);\n          });\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  }\n});\n\n// apply for a job [todo: test: done]\nrouter.post(\"/jobs/:id/applications\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type != \"applicant\") {\n    res.status(401).json({\n      message: \"You don't have permissions to apply for a job\",\n    });\n    return;\n  }\n  const data = req.body;\n  const jobId = req.params.id;\n\n  // check whether applied previously\n  // find job\n  // check count of active applications < limit\n  // check user had < 10 active applications && check if user is not having any accepted jobs (user id)\n  // store the data in applications\n\n  Application.findOne({\n    userId: user._id,\n    jobId: jobId,\n    status: {\n      $nin: [\"deleted\", \"accepted\", \"cancelled\"],\n    },\n  })\n    .then((appliedApplication) => {\n      console.log(appliedApplication);\n      if (appliedApplication !== null) {\n        res.status(400).json({\n          message: \"You have already applied for this job\",\n        });\n        return;\n      }\n\n      Job.findOne({ _id: jobId })\n        .then((job) => {\n          if (job === null) {\n            res.status(404).json({\n              message: \"Job does not exist\",\n            });\n            return;\n          }\n          Application.countDocuments({\n            jobId: jobId,\n            status: {\n              $nin: [\"rejected\", \"deleted\", \"cancelled\", \"finished\"],\n            },\n          })\n            .then((activeApplicationCount) => {\n              if (activeApplicationCount < job.maxApplicants) {\n                Application.countDocuments({\n                  userId: user._id,\n                  status: {\n                    $nin: [\"rejected\", \"deleted\", \"cancelled\", \"finished\"],\n                  },\n                })\n                  .then((myActiveApplicationCount) => {\n                    if (myActiveApplicationCount < 10) {\n                      Application.countDocuments({\n                        userId: user._id,\n                        status: \"accepted\",\n                      }).then((acceptedJobs) => {\n                        if (acceptedJobs === 0) {\n                          const application = new Application({\n                            userId: user._id,\n                            recruiterId: job.userId,\n                            jobId: job._id,\n                            status: \"applied\",\n                            sop: data.sop,\n                          });\n                          application\n                            .save()\n                            .then(() => {\n                              res.json({\n                                message: \"Job application successful\",\n                              });\n                            })\n                            .catch((err) => {\n                              res.status(400).json(err);\n                            });\n                        } else {\n                          res.status(400).json({\n                            message:\n                              \"You already have an accepted job. Hence you cannot apply.\",\n                          });\n                        }\n                      });\n                    } else {\n                      res.status(400).json({\n                        message:\n                          \"You have 10 active applications. Hence you cannot apply.\",\n                      });\n                    }\n                  })\n                  .catch((err) => {\n                    res.status(400).json(err);\n                  });\n              } else {\n                res.status(400).json({\n                  message: \"Application limit reached\",\n                });\n              }\n            })\n            .catch((err) => {\n              res.status(400).json(err);\n            });\n        })\n        .catch((err) => {\n          res.status(400).json(err);\n        });\n    })\n    .catch((err) => {\n      res.json(400).json(err);\n    });\n});\n\n// recruiter gets applications for a particular job [pagination] [todo: test: done]\nrouter.get(\"/jobs/:id/applications\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type != \"recruiter\") {\n    res.status(401).json({\n      message: \"You don't have permissions to view job applications\",\n    });\n    return;\n  }\n  const jobId = req.params.id;\n\n  // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;\n  // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;\n  // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;\n\n  let findParams = {\n    jobId: jobId,\n    recruiterId: user._id,\n  };\n\n  let sortParams = {};\n\n  if (req.query.status) {\n    findParams = {\n      ...findParams,\n      status: req.query.status,\n    };\n  }\n\n  Application.find(findParams)\n    .collation({ locale: \"en\" })\n    .sort(sortParams)\n    // .skip(skip)\n    // .limit(limit)\n    .then((applications) => {\n      res.json(applications);\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// recruiter/applicant gets all his applications [pagination]\nrouter.get(\"/applications\", jwtAuth, (req, res) => {\n  const user = req.user;\n\n  // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;\n  // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;\n  // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;\n\n  Application.aggregate([\n    {\n      $lookup: {\n        from: \"jobapplicantinfos\",\n        localField: \"userId\",\n        foreignField: \"userId\",\n        as: \"jobApplicant\",\n      },\n    },\n    { $unwind: \"$jobApplicant\" },\n    {\n      $lookup: {\n        from: \"jobs\",\n        localField: \"jobId\",\n        foreignField: \"_id\",\n        as: \"job\",\n      },\n    },\n    { $unwind: \"$job\" },\n    {\n      $lookup: {\n        from: \"recruiterinfos\",\n        localField: \"recruiterId\",\n        foreignField: \"userId\",\n        as: \"recruiter\",\n      },\n    },\n    { $unwind: \"$recruiter\" },\n    {\n      $match: {\n        [user.type === \"recruiter\" ? \"recruiterId\" : \"userId\"]: user._id,\n      },\n    },\n    {\n      $sort: {\n        dateOfApplication: -1,\n      },\n    },\n  ])\n    .then((applications) => {\n      res.json(applications);\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\n// update status of application: [Applicant: Can cancel, Recruiter: Can do everything] [todo: test: done]\nrouter.put(\"/applications/:id\", jwtAuth, (req, res) => {\n  const user = req.user;\n  const id = req.params.id;\n  const status = req.body.status;\n\n  // \"applied\", // when a applicant is applied\n  // \"shortlisted\", // when a applicant is shortlisted\n  // \"accepted\", // when a applicant is accepted\n  // \"rejected\", // when a applicant is rejected\n  // \"deleted\", // when any job is deleted\n  // \"cancelled\", // an application is cancelled by its author or when other application is accepted\n  // \"finished\", // when job is over\n\n  if (user.type === \"recruiter\") {\n    if (status === \"accepted\") {\n      // get job id from application\n      // get job info for maxPositions count\n      // count applications that are already accepted\n      // compare and if condition is satisfied, then save\n\n      Application.findOne({\n        _id: id,\n        recruiterId: user._id,\n      })\n        .then((application) => {\n          if (application === null) {\n            res.status(404).json({\n              message: \"Application not found\",\n            });\n            return;\n          }\n\n          Job.findOne({\n            _id: application.jobId,\n            userId: user._id,\n          }).then((job) => {\n            if (job === null) {\n              res.status(404).json({\n                message: \"Job does not exist\",\n              });\n              return;\n            }\n\n            Application.countDocuments({\n              recruiterId: user._id,\n              jobId: job._id,\n              status: \"accepted\",\n            }).then((activeApplicationCount) => {\n              if (activeApplicationCount < job.maxPositions) {\n                // accepted\n                application.status = status;\n                application.dateOfJoining = req.body.dateOfJoining;\n                application\n                  .save()\n                  .then(() => {\n                    Application.updateMany(\n                      {\n                        _id: {\n                          $ne: application._id,\n                        },\n                        userId: application.userId,\n                        status: {\n                          $nin: [\n                            \"rejected\",\n                            \"deleted\",\n                            \"cancelled\",\n                            \"accepted\",\n                            \"finished\",\n                          ],\n                        },\n                      },\n                      {\n                        $set: {\n                          status: \"cancelled\",\n                        },\n                      },\n                      { multi: true }\n                    )\n                      .then(() => {\n                        if (status === \"accepted\") {\n                          Job.findOneAndUpdate(\n                            {\n                              _id: job._id,\n                              userId: user._id,\n                            },\n                            {\n                              $set: {\n                                acceptedCandidates: activeApplicationCount + 1,\n                              },\n                            }\n                          )\n                            .then(() => {\n                              res.json({\n                                message: `Application ${status} successfully`,\n                              });\n                            })\n                            .catch((err) => {\n                              res.status(400).json(err);\n                            });\n                        } else {\n                          res.json({\n                            message: `Application ${status} successfully`,\n                          });\n                        }\n                      })\n                      .catch((err) => {\n                        res.status(400).json(err);\n                      });\n                  })\n                  .catch((err) => {\n                    res.status(400).json(err);\n                  });\n              } else {\n                res.status(400).json({\n                  message: \"All positions for this job are already filled\",\n                });\n              }\n            });\n          });\n        })\n        .catch((err) => {\n          res.status(400).json(err);\n        });\n    } else {\n      Application.findOneAndUpdate(\n        {\n          _id: id,\n          recruiterId: user._id,\n          status: {\n            $nin: [\"rejected\", \"deleted\", \"cancelled\"],\n          },\n        },\n        {\n          $set: {\n            status: status,\n          },\n        }\n      )\n        .then((application) => {\n          if (application === null) {\n            res.status(400).json({\n              message: \"Application status cannot be updated\",\n            });\n            return;\n          }\n          if (status === \"finished\") {\n            res.json({\n              message: `Job ${status} successfully`,\n            });\n          } else {\n            res.json({\n              message: `Application ${status} successfully`,\n            });\n          }\n        })\n        .catch((err) => {\n          res.status(400).json(err);\n        });\n    }\n  } else {\n    if (status === \"cancelled\") {\n      console.log(id);\n      console.log(user._id);\n      Application.findOneAndUpdate(\n        {\n          _id: id,\n          userId: user._id,\n        },\n        {\n          $set: {\n            status: status,\n          },\n        }\n      )\n        .then((tmp) => {\n          console.log(tmp);\n          res.json({\n            message: `Application ${status} successfully`,\n          });\n        })\n        .catch((err) => {\n          res.status(400).json(err);\n        });\n    } else {\n      res.status(401).json({\n        message: \"You don't have permissions to update job status\",\n      });\n    }\n  }\n});\n\n// get a list of final applicants for current job : recruiter\n// get a list of final applicants for all his jobs : recuiter\nrouter.get(\"/applicants\", jwtAuth, (req, res) => {\n  const user = req.user;\n  if (user.type === \"recruiter\") {\n    let findParams = {\n      recruiterId: user._id,\n    };\n    if (req.query.jobId) {\n      findParams = {\n        ...findParams,\n        jobId: new mongoose.Types.ObjectId(req.query.jobId),\n      };\n    }\n    if (req.query.status) {\n      if (Array.isArray(req.query.status)) {\n        findParams = {\n          ...findParams,\n          status: { $in: req.query.status },\n        };\n      } else {\n        findParams = {\n          ...findParams,\n          status: req.query.status,\n        };\n      }\n    }\n    let sortParams = {};\n\n    if (!req.query.asc && !req.query.desc) {\n      sortParams = { _id: 1 };\n    }\n\n    if (req.query.asc) {\n      if (Array.isArray(req.query.asc)) {\n        req.query.asc.map((key) => {\n          sortParams = {\n            ...sortParams,\n            [key]: 1,\n          };\n        });\n      } else {\n        sortParams = {\n          ...sortParams,\n          [req.query.asc]: 1,\n        };\n      }\n    }\n\n    if (req.query.desc) {\n      if (Array.isArray(req.query.desc)) {\n        req.query.desc.map((key) => {\n          sortParams = {\n            ...sortParams,\n            [key]: -1,\n          };\n        });\n      } else {\n        sortParams = {\n          ...sortParams,\n          [req.query.desc]: -1,\n        };\n      }\n    }\n\n    Application.aggregate([\n      {\n        $lookup: {\n          from: \"jobapplicantinfos\",\n          localField: \"userId\",\n          foreignField: \"userId\",\n          as: \"jobApplicant\",\n        },\n      },\n      { $unwind: \"$jobApplicant\" },\n      {\n        $lookup: {\n          from: \"jobs\",\n          localField: \"jobId\",\n          foreignField: \"_id\",\n          as: \"job\",\n        },\n      },\n      { $unwind: \"$job\" },\n      { $match: findParams },\n      { $sort: sortParams },\n    ])\n      .then((applications) => {\n        if (applications.length === 0) {\n          res.status(404).json({\n            message: \"No applicants found\",\n          });\n          return;\n        }\n        res.json(applications);\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  } else {\n    res.status(400).json({\n      message: \"You are not allowed to access applicants list\",\n    });\n  }\n});\n\n// to add or update a rating [todo: test]\nrouter.put(\"/rating\", jwtAuth, (req, res) => {\n  const user = req.user;\n  const data = req.body;\n  if (user.type === \"recruiter\") {\n    // can rate applicant\n    Rating.findOne({\n      senderId: user._id,\n      receiverId: data.applicantId,\n      category: \"applicant\",\n    })\n      .then((rating) => {\n        if (rating === null) {\n          console.log(\"new rating\");\n          Application.countDocuments({\n            userId: data.applicantId,\n            recruiterId: user._id,\n            status: {\n              $in: [\"accepted\", \"finished\"],\n            },\n          })\n            .then((acceptedApplicant) => {\n              if (acceptedApplicant > 0) {\n                // add a new rating\n\n                rating = new Rating({\n                  category: \"applicant\",\n                  receiverId: data.applicantId,\n                  senderId: user._id,\n                  rating: data.rating,\n                });\n\n                rating\n                  .save()\n                  .then(() => {\n                    // get the average of ratings\n                    Rating.aggregate([\n                      {\n                        $match: {\n                          receiverId: mongoose.Types.ObjectId(data.applicantId),\n                          category: \"applicant\",\n                        },\n                      },\n                      {\n                        $group: {\n                          _id: {},\n                          average: { $avg: \"$rating\" },\n                        },\n                      },\n                    ])\n                      .then((result) => {\n                        // update the user's rating\n                        if (result === null) {\n                          res.status(400).json({\n                            message: \"Error while calculating rating\",\n                          });\n                          return;\n                        }\n                        const avg = result[0].average;\n\n                        JobApplicant.findOneAndUpdate(\n                          {\n                            userId: data.applicantId,\n                          },\n                          {\n                            $set: {\n                              rating: avg,\n                            },\n                          }\n                        )\n                          .then((applicant) => {\n                            if (applicant === null) {\n                              res.status(400).json({\n                                message:\n                                  \"Error while updating applicant's average rating\",\n                              });\n                              return;\n                            }\n                            res.json({\n                              message: \"Rating added successfully\",\n                            });\n                          })\n                          .catch((err) => {\n                            res.status(400).json(err);\n                          });\n                      })\n                      .catch((err) => {\n                        res.status(400).json(err);\n                      });\n                  })\n                  .catch((err) => {\n                    res.status(400).json(err);\n                  });\n              } else {\n                // you cannot rate\n                res.status(400).json({\n                  message:\n                    \"Applicant didn't worked under you. Hence you cannot give a rating.\",\n                });\n              }\n            })\n            .catch((err) => {\n              res.status(400).json(err);\n            });\n        } else {\n          rating.rating = data.rating;\n          rating\n            .save()\n            .then(() => {\n              // get the average of ratings\n              Rating.aggregate([\n                {\n                  $match: {\n                    receiverId: mongoose.Types.ObjectId(data.applicantId),\n                    category: \"applicant\",\n                  },\n                },\n                {\n                  $group: {\n                    _id: {},\n                    average: { $avg: \"$rating\" },\n                  },\n                },\n              ])\n                .then((result) => {\n                  // update the user's rating\n                  if (result === null) {\n                    res.status(400).json({\n                      message: \"Error while calculating rating\",\n                    });\n                    return;\n                  }\n                  const avg = result[0].average;\n                  JobApplicant.findOneAndUpdate(\n                    {\n                      userId: data.applicantId,\n                    },\n                    {\n                      $set: {\n                        rating: avg,\n                      },\n                    }\n                  )\n                    .then((applicant) => {\n                      if (applicant === null) {\n                        res.status(400).json({\n                          message:\n                            \"Error while updating applicant's average rating\",\n                        });\n                        return;\n                      }\n                      res.json({\n                        message: \"Rating updated successfully\",\n                      });\n                    })\n                    .catch((err) => {\n                      res.status(400).json(err);\n                    });\n                })\n                .catch((err) => {\n                  res.status(400).json(err);\n                });\n            })\n            .catch((err) => {\n              res.status(400).json(err);\n            });\n        }\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  } else {\n    // applicant can rate job\n    Rating.findOne({\n      senderId: user._id,\n      receiverId: data.jobId,\n      category: \"job\",\n    })\n      .then((rating) => {\n        console.log(user._id);\n        console.log(data.jobId);\n        console.log(rating);\n        if (rating === null) {\n          console.log(rating);\n          Application.countDocuments({\n            userId: user._id,\n            jobId: data.jobId,\n            status: {\n              $in: [\"accepted\", \"finished\"],\n            },\n          })\n            .then((acceptedApplicant) => {\n              if (acceptedApplicant > 0) {\n                // add a new rating\n\n                rating = new Rating({\n                  category: \"job\",\n                  receiverId: data.jobId,\n                  senderId: user._id,\n                  rating: data.rating,\n                });\n\n                rating\n                  .save()\n                  .then(() => {\n                    // get the average of ratings\n                    Rating.aggregate([\n                      {\n                        $match: {\n                          receiverId: mongoose.Types.ObjectId(data.jobId),\n                          category: \"job\",\n                        },\n                      },\n                      {\n                        $group: {\n                          _id: {},\n                          average: { $avg: \"$rating\" },\n                        },\n                      },\n                    ])\n                      .then((result) => {\n                        if (result === null) {\n                          res.status(400).json({\n                            message: \"Error while calculating rating\",\n                          });\n                          return;\n                        }\n                        const avg = result[0].average;\n                        Job.findOneAndUpdate(\n                          {\n                            _id: data.jobId,\n                          },\n                          {\n                            $set: {\n                              rating: avg,\n                            },\n                          }\n                        )\n                          .then((foundJob) => {\n                            if (foundJob === null) {\n                              res.status(400).json({\n                                message:\n                                  \"Error while updating job's average rating\",\n                              });\n                              return;\n                            }\n                            res.json({\n                              message: \"Rating added successfully\",\n                            });\n                          })\n                          .catch((err) => {\n                            res.status(400).json(err);\n                          });\n                      })\n                      .catch((err) => {\n                        res.status(400).json(err);\n                      });\n                  })\n                  .catch((err) => {\n                    res.status(400).json(err);\n                  });\n              } else {\n                // you cannot rate\n                res.status(400).json({\n                  message:\n                    \"You haven't worked for this job. Hence you cannot give a rating.\",\n                });\n              }\n            })\n            .catch((err) => {\n              res.status(400).json(err);\n            });\n        } else {\n          // update the rating\n          rating.rating = data.rating;\n          rating\n            .save()\n            .then(() => {\n              // get the average of ratings\n              Rating.aggregate([\n                {\n                  $match: {\n                    receiverId: mongoose.Types.ObjectId(data.jobId),\n                    category: \"job\",\n                  },\n                },\n                {\n                  $group: {\n                    _id: {},\n                    average: { $avg: \"$rating\" },\n                  },\n                },\n              ])\n                .then((result) => {\n                  if (result === null) {\n                    res.status(400).json({\n                      message: \"Error while calculating rating\",\n                    });\n                    return;\n                  }\n                  const avg = result[0].average;\n                  console.log(avg);\n\n                  Job.findOneAndUpdate(\n                    {\n                      _id: data.jobId,\n                    },\n                    {\n                      $set: {\n                        rating: avg,\n                      },\n                    }\n                  )\n                    .then((foundJob) => {\n                      if (foundJob === null) {\n                        res.status(400).json({\n                          message: \"Error while updating job's average rating\",\n                        });\n                        return;\n                      }\n                      res.json({\n                        message: \"Rating added successfully\",\n                      });\n                    })\n                    .catch((err) => {\n                      res.status(400).json(err);\n                    });\n                })\n                .catch((err) => {\n                  res.status(400).json(err);\n                });\n            })\n            .catch((err) => {\n              res.status(400).json(err);\n            });\n        }\n      })\n      .catch((err) => {\n        res.status(400).json(err);\n      });\n  }\n});\n\n// get personal rating\nrouter.get(\"/rating\", jwtAuth, (req, res) => {\n  const user = req.user;\n  Rating.findOne({\n    senderId: user._id,\n    receiverId: req.query.id,\n    category: user.type === \"recruiter\" ? \"applicant\" : \"job\",\n  }).then((rating) => {\n    if (rating === null) {\n      res.json({\n        rating: -1,\n      });\n      return;\n    }\n    res.json({\n      rating: rating.rating,\n    });\n  });\n});\n\n// Application.findOne({\n//   _id: id,\n//   userId: user._id,\n// })\n//   .then((application) => {\n//     application.status = status;\n//     application\n//       .save()\n//       .then(() => {\n//         res.json({\n//           message: `Application ${status} successfully`,\n//         });\n//       })\n//       .catch((err) => {\n//         res.status(400).json(err);\n//       });\n//   })\n//   .catch((err) => {\n//     res.status(400).json(err);\n//   });\n\n// router.get(\"/jobs\", (req, res, next) => {\n//   passport.authenticate(\"jwt\", { session: false }, function (err, user, info) {\n//     if (err) {\n//       return next(err);\n//     }\n//     if (!user) {\n//       res.status(401).json(info);\n//       return;\n//     }\n//   })(req, res, next);\n// });\n\nmodule.exports = router;\n"
  },
  {
    "path": "backend/routes/authRoutes.js",
    "content": "const express = require(\"express\");\nconst passport = require(\"passport\");\nconst jwt = require(\"jsonwebtoken\");\nconst authKeys = require(\"../lib/authKeys\");\n\nconst User = require(\"../db/User\");\nconst JobApplicant = require(\"../db/JobApplicant\");\nconst Recruiter = require(\"../db/Recruiter\");\n\nconst router = express.Router();\n\nrouter.post(\"/signup\", (req, res) => {\n  const data = req.body;\n  let user = new User({\n    email: data.email,\n    password: data.password,\n    type: data.type,\n  });\n\n  user\n    .save()\n    .then(() => {\n      const userDetails =\n        user.type == \"recruiter\"\n          ? new Recruiter({\n              userId: user._id,\n              name: data.name,\n              contactNumber: data.contactNumber,\n              bio: data.bio,\n            })\n          : new JobApplicant({\n              userId: user._id,\n              name: data.name,\n              education: data.education,\n              skills: data.skills,\n              rating: data.rating,\n              resume: data.resume,\n              profile: data.profile,\n            });\n\n      userDetails\n        .save()\n        .then(() => {\n          // Token\n          const token = jwt.sign({ _id: user._id }, authKeys.jwtSecretKey);\n          res.json({\n            token: token,\n            type: user.type,\n          });\n        })\n        .catch((err) => {\n          user\n            .delete()\n            .then(() => {\n              res.status(400).json(err);\n            })\n            .catch((err) => {\n              res.json({ error: err });\n            });\n          err;\n        });\n    })\n    .catch((err) => {\n      res.status(400).json(err);\n    });\n});\n\nrouter.post(\"/login\", (req, res, next) => {\n  passport.authenticate(\n    \"local\",\n    { session: false },\n    function (err, user, info) {\n      if (err) {\n        return next(err);\n      }\n      if (!user) {\n        res.status(401).json(info);\n        return;\n      }\n      // Token\n      const token = jwt.sign({ _id: user._id }, authKeys.jwtSecretKey);\n      res.json({\n        token: token,\n        type: user.type,\n      });\n    }\n  )(req, res, next);\n});\n\nmodule.exports = router;\n"
  },
  {
    "path": "backend/routes/downloadRoutes.js",
    "content": "const express = require(\"express\");\nconst fs = require(\"fs\");\nconst path = require(\"path\");\n\nconst router = express.Router();\n\nrouter.get(\"/resume/:file\", (req, res) => {\n  const address = path.join(__dirname, `../public/resume/${req.params.file}`);\n  fs.access(address, fs.F_OK, (err) => {\n    if (err) {\n      res.status(404).json({\n        message: \"File not found\",\n      });\n      return;\n    }\n    res.sendFile(address);\n  });\n});\n\nrouter.get(\"/profile/:file\", (req, res) => {\n  const address = path.join(__dirname, `../public/profile/${req.params.file}`);\n  fs.access(address, fs.F_OK, (err) => {\n    if (err) {\n      res.status(404).json({\n        message: \"File not found\",\n      });\n      return;\n    }\n    res.sendFile(address);\n  });\n});\n\nmodule.exports = router;\n"
  },
  {
    "path": "backend/routes/uploadRoutes.js",
    "content": "const express = require(\"express\");\nconst multer = require(\"multer\");\nconst fs = require(\"fs\");\nconst { v4: uuidv4 } = require(\"uuid\");\nconst { promisify } = require(\"util\");\n\nconst pipeline = promisify(require(\"stream\").pipeline);\n\nconst router = express.Router();\n\nconst upload = multer();\n\nrouter.post(\"/resume\", upload.single(\"file\"), (req, res) => {\n  const { file } = req;\n  if (file.detectedFileExtension != \".pdf\") {\n    res.status(400).json({\n      message: \"Invalid format\",\n    });\n  } else {\n    const filename = `${uuidv4()}${file.detectedFileExtension}`;\n\n    pipeline(\n      file.stream,\n      fs.createWriteStream(`${__dirname}/../public/resume/${filename}`)\n    )\n      .then(() => {\n        res.send({\n          message: \"File uploaded successfully\",\n          url: `/host/resume/${filename}`,\n        });\n      })\n      .catch((err) => {\n        res.status(400).json({\n          message: \"Error while uploading\",\n        });\n      });\n  }\n});\n\nrouter.post(\"/profile\", upload.single(\"file\"), (req, res) => {\n  const { file } = req;\n  if (\n    file.detectedFileExtension != \".jpg\" &&\n    file.detectedFileExtension != \".png\"\n  ) {\n    res.status(400).json({\n      message: \"Invalid format\",\n    });\n  } else {\n    const filename = `${uuidv4()}${file.detectedFileExtension}`;\n\n    pipeline(\n      file.stream,\n      fs.createWriteStream(`${__dirname}/../public/profile/${filename}`)\n    )\n      .then(() => {\n        res.send({\n          message: \"Profile image uploaded successfully\",\n          url: `/host/profile/${filename}`,\n        });\n      })\n      .catch((err) => {\n        res.status(400).json({\n          message: \"Error while uploading\",\n        });\n      });\n  }\n});\n\nmodule.exports = router;\n"
  },
  {
    "path": "backend/server.js",
    "content": "const express = require(\"express\");\nconst bodyParser = require(\"body-parser\");\nconst mongoose = require(\"mongoose\");\nconst passportConfig = require(\"./lib/passportConfig\");\nconst cors = require(\"cors\");\nconst fs = require(\"fs\");\n\n// MongoDB\nmongoose\n  .connect(\"mongodb://localhost:27017/jobPortal\", {\n    useNewUrlParser: true,\n    useUnifiedTopology: true,\n    useCreateIndex: true,\n    useFindAndModify: false,\n  })\n  .then((res) => console.log(\"Connected to DB\"))\n  .catch((err) => console.log(err));\n\n// initialising directories\nif (!fs.existsSync(\"./public\")) {\n  fs.mkdirSync(\"./public\");\n}\nif (!fs.existsSync(\"./public/resume\")) {\n  fs.mkdirSync(\"./public/resume\");\n}\nif (!fs.existsSync(\"./public/profile\")) {\n  fs.mkdirSync(\"./public/profile\");\n}\n\nconst app = express();\nconst port = 4444;\n\napp.use(bodyParser.json()); // support json encoded bodies\napp.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies\n\n// Setting up middlewares\napp.use(cors());\napp.use(express.json());\napp.use(passportConfig.initialize());\n\n// Routing\napp.use(\"/auth\", require(\"./routes/authRoutes\"));\napp.use(\"/api\", require(\"./routes/apiRoutes\"));\napp.use(\"/upload\", require(\"./routes/uploadRoutes\"));\napp.use(\"/host\", require(\"./routes/downloadRoutes\"));\n\napp.listen(port, () => {\n  console.log(`Server started on port ${port}!`);\n});\n"
  },
  {
    "path": "dummyData",
    "content": "\nPOST\nlocalhost:4444/auth/signup\n\n// recruiter\n\n{\n    \"email\": \"john@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"recruiter\",\n    \"name\": \"John Smith\",\n    \"contactNumber\": \"+91-7979282839\",\n    \"bio\": \"I am a recruiter from Google Inc\"\n}\n\n{\n    \"email\": \"roman@live.in\",\n    \"password\": \"test\",\n    \"type\": \"recruiter\",\n    \"name\": \"Roman Reigns\",\n    \"contactNumber\": \"+91-8879456123\",\n    \"bio\": \"I am a recruiter from Amazon Inc\"\n}\n\n// applicant\n\n{\n    \"email\": \"shlok@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"applicant\",\n    \"name\": \"Shlok Pandey\",\n    \"education\": [\n        {\n            \"institutionName\": \"DPS Azaad Nagar\",\n            \"startYear\": 2009,\n            \"endYear\": 2018\n        },\n        {\n            \"institutionName\": \"IIIT Sri City\",\n            \"startYear\": 2018,\n            \"endYear\": 2020\n        },\n        {\n            \"institutionName\": \"IIIT Hyderabad\",\n            \"startYear\": 2020\n        }\n    ],\n    \"skills\": [\n        \"JavaScript\",\n        \"React JS\",\n        \"Django\"\n    ]\n}\n\n{\n    \"email\": \"ash@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"applicant\",\n    \"name\": \"Ashwani Shukla\",\n    \"education\": [\n        {\n            \"institutionName\": \"Allenhouse College\",\n            \"startYear\": 2019\n        }\n    ],\n    \"skills\": [\n        \"C\",\n        \"C++\",\n        \"Web Development\"\n    ]\n}\n\n// Login\n\nPOST\nlocalhost:4444/auth/login\n\n\n{\n    \"email\": \"john@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"recruiter\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA1NzMzNWMzNWQ1NTJlMDU5NzA1YzYiLCJpYXQiOjE2MTA5Njk5MDl9.6f4qhjHIaRU_lnY74WB2mK_h7uo32tp1V4uf3DVN5GQ\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4NTk5ZTIwODQyZjA1YTE3NzU4ZjkiLCJpYXQiOjE2MTExNTk5NjZ9.DIGyjwezwheqFkex0dZSIOEKrEUXXSNka9Va2B2rYVc\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4Njg0Mzk1ZTUxMDIwYmI2OTVlZGEiLCJpYXQiOjE2MTExNjM3MTV9.6UlyrgwLvM0o8tXcihJVWTnnJNO0WlBXAAF8RKmlgRQ\"\n}\n\n{\n    \"email\": \"roman@live.in\",\n    \"password\": \"test\",\n    \"type\": \"recruiter\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA1NzM2N2MzNWQ1NTJlMDU5NzA1YzkiLCJpYXQiOjE2MTA5Njk5NTl9.KVjgEa8U0BcZQ4pfJd1mr2h-CP6ZBOJKanFhmQQFDPo\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4NTllNDIwODQyZjA1YTE3NzU4ZmMiLCJpYXQiOjE2MTExNjAwMzZ9.FA0jrx3d1en4zP3ElDkRtUV1pulgPDIpVeXOfBTIy80\"\n}\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4Njg1OTk1ZTUxMDIwYmI2OTVlZGMiLCJpYXQiOjE2MTExNjM3Mzd9.zLS_VltLBVTXcGqzO4jGjrZ4OagxL2U5MXjcdLn5jNY\"\n}\n\n{\n    \"email\": \"shlok@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"applicant\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA1NzM4YWMzNWQ1NTJlMDU5NzA1Y2IiLCJpYXQiOjE2MTA5Njk5OTR9.8pb8nBN0npAT_uW-2OJV8DuqXDJlPy_HOjm_MdQUwLA\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4NWEwMjIwODQyZjA1YTE3NzU4ZmUiLCJpYXQiOjE2MTExNjAwNjZ9.P4NLHyah0O6ISH4LSkEAna7g-YovyM1ArnVGJ54TcEw\"\n}\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4Njg2Yzk1ZTUxMDIwYmI2OTVlZGUiLCJpYXQiOjE2MTExNjM3NTd9.UuqeMrMGYGJ3tJtvs8Z9VgLxqIF6QUHKjU9EIbQ8Pjc\"\n}\n\n{\n    \"email\": \"ash@gmail.com\",\n    \"password\": \"test\",\n    \"type\": \"applicant\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA1NzNhMWMzNWQ1NTJlMDU5NzA1ZDAiLCJpYXQiOjE2MTA5NzAwMTd9.oL617v51AErVlaPGr1oP-5ILQbA9DO2DAoQRFtLh52U\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4NWExNjIwODQyZjA1YTE3NzU5MDMiLCJpYXQiOjE2MTExNjAwODd9.YoYpauFDzF28ZzKkeItbRPdcqw8biNKujNfZCGCKibw\"\n}\n\n{\n    \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MDA4Njg4Mzk1ZTUxMDIwYmI2OTVlZTMiLCJpYXQiOjE2MTExNjM3Nzl9.iFPFXu3aOax6muoCzNJavGSKa9s87S5AIXTiHvJ0OSQ\"\n}\n\n// jobs\n\nGET\nlocalhost:4444/api/jobs\n\nPOST\nlocalhost:4444/api/jobs\n\nAdmin 1\n\n{\n    \"title\": \"Software Development Intern\",\n    \"maxApplicants\": 5,\n    \"maxPositions\": 1,\n    \"deadline\": \"2021-02-22T18:17:24.519Z\",\n    \"skillsets\": [\"C\", \"C++\", \"Javascript\"],\n    \"jobType\": \"Internship\",\n    \"duration\": 2,\n    \"salary\": 4000\n}\n\n{\n    \"title\": \"Web Development(Full Time)\",\n    \"maxApplicants\": 1,\n    \"maxPositions\": 1,\n    \"deadline\": \"2021-02-20T18:17:24.519Z\",\n    \"skillsets\": [\"PHP\", \"Django\"],\n    \"jobType\": \"Full Time\",\n    \"duration\": 0,\n    \"salary\": 5000\n}\n\nAdmin 2\n\n{\n    \"title\": \"Full Stack Intern\",\n    \"maxApplicants\": 5,\n    \"maxPositions\": 3,\n    \"deadline\": \"2021-02-20T18:17:24.519Z\",\n    \"skillsets\": [\"ReactJS\", \"NodeJS\", \"Express\"],\n    \"jobType\": \"Internship\",\n    \"duration\": 5,\n    \"salary\": 4500\n}\n\n// view a job\n// delete a job\n\n// update a job\n\n{\n    \"maxApplicants\": 4,\n    \"maxPositions\": 2,\n    \"deadline\": \"2021-02-21T18:17:24.519Z\"\n}\n\n\n// get user personal details\nGET\nlocalhost:4444/api/user\n\n// update user details\nPUT\nlocalhost:4444/api/user\n\n{\n    \"name\": \"Roman Rollins\",\n    \"contactNumber\": \"+91-8945659878\",\n    \"bio\": \"I am a recruiter from Flipkart Inc\",\n}\n\n// job application\n\n{\n    \"sop\": \"Shlok: I wouldn't let you down\"\n}\n\n{\n    \"sop\": \"Ashwani: I hope you like my resume.\"\n}\n\n// update status\n\n// for client side\n{\n    \"status\": \"cancelled\"\n}\n\n{\n    \"status\": \"shortlisted\"\n}\n\n{\n    \"status\": \"rejected\"\n}\n\n{\n    \"status\": \"accepted\"\n}\n\n{\n    \"status\": \"finished\"\n}\n\n// test rating\n\n{\n    \"applicantId\": \"6005738ac35d552e059705cb\",\n    \"rating\": 4.2\n}\n\n{\n    \"applicantId\": \"600573a1c35d552e059705d0\",\n    \"rating\": 3.5\n}\n\n{\n    \"jobId\": \"600576e16ce7b7325f5b5c70\",\n    \"rating\": 2.0\n}"
  },
  {
    "path": "frontend/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "frontend/README.md",
    "content": "# Getting Started with Create React App\n\nThis project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).\n\n## Available Scripts\n\nIn the project directory, you can run:\n\n### `npm start`\n\nRuns the app in the development mode.\\\nOpen [http://localhost:3000](http://localhost:3000) to view it in the browser.\n\nThe page will reload if you make edits.\\\nYou will also see any lint errors in the console.\n\n### `npm test`\n\nLaunches the test runner in the interactive watch mode.\\\nSee the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.\n\n### `npm run build`\n\nBuilds the app for production to the `build` folder.\\\nIt correctly bundles React in production mode and optimizes the build for the best performance.\n\nThe build is minified and the filenames include the hashes.\\\nYour app is ready to be deployed!\n\nSee the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.\n\n### `npm run eject`\n\n**Note: this is a one-way operation. Once you `eject`, you can’t go back!**\n\nIf 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.\n\nInstead, 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.\n\nYou 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.\n\n## Learn More\n\nYou can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).\n\nTo learn React, check out the [React documentation](https://reactjs.org/).\n\n### Code Splitting\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)\n\n### Analyzing the Bundle Size\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)\n\n### Making a Progressive Web App\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)\n\n### Advanced Configuration\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)\n\n### Deployment\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)\n\n### `npm run build` fails to minify\n\nThis section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)\n"
  },
  {
    "path": "frontend/package.json",
    "content": "{\n  \"name\": \"job-portal\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@material-ui/core\": \"^4.11.2\",\n    \"@material-ui/icons\": \"^4.11.2\",\n    \"@material-ui/lab\": \"^4.0.0-alpha.57\",\n    \"@testing-library/jest-dom\": \"^5.11.9\",\n    \"@testing-library/react\": \"^11.2.3\",\n    \"@testing-library/user-event\": \"^12.6.2\",\n    \"axios\": \"^0.21.1\",\n    \"material-ui-chip-input\": \"^1.1.0\",\n    \"react\": \"^17.0.1\",\n    \"react-dom\": \"^17.0.1\",\n    \"react-phone-input-2\": \"^2.13.9\",\n    \"react-router-dom\": \"^5.2.0\",\n    \"react-scripts\": \"4.0.1\",\n    \"web-vitals\": \"^0.2.4\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\"\n  },\n  \"eslintConfig\": {\n    \"extends\": [\n      \"react-app\",\n      \"react-app/jest\"\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  }\n}\n"
  },
  {
    "path": "frontend/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <meta name=\"theme-color\" content=\"#000000\" />\n    <meta\n      name=\"description\"\n      content=\"Web site created using create-react-app\"\n    />\n    <link rel=\"apple-touch-icon\" href=\"%PUBLIC_URL%/logo192.png\" />\n    <!--\n      manifest.json provides metadata used when your web app is installed on a\n      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n    -->\n    <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n    <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>React App</title>\n  </head>\n  <body>\n    <noscript>You need to enable JavaScript to run this app.</noscript>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "frontend/public/manifest.json",
    "content": "{\n  \"short_name\": \"React App\",\n  \"name\": \"Create React App Sample\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    },\n    {\n      \"src\": \"logo192.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"192x192\"\n    },\n    {\n      \"src\": \"logo512.png\",\n      \"type\": \"image/png\",\n      \"sizes\": \"512x512\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "frontend/public/robots.txt",
    "content": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "frontend/src/App.css",
    "content": ""
  },
  {
    "path": "frontend/src/App.js",
    "content": "import { createContext, useState } from \"react\";\nimport { BrowserRouter, Switch, Route } from \"react-router-dom\";\nimport { Grid, makeStyles } from \"@material-ui/core\";\n\nimport Welcome, { ErrorPage } from \"./component/Welcome\";\nimport Navbar from \"./component/Navbar\";\nimport Login from \"./component/Login\";\nimport Logout from \"./component/Logout\";\nimport Signup from \"./component/Signup\";\nimport Home from \"./component/Home\";\nimport Applications from \"./component/Applications\";\nimport Profile from \"./component/Profile\";\nimport CreateJobs from \"./component/recruiter/CreateJobs\";\nimport MyJobs from \"./component/recruiter/MyJobs\";\nimport JobApplications from \"./component/recruiter/JobApplications\";\nimport AcceptedApplicants from \"./component/recruiter/AcceptedApplicants\";\nimport RecruiterProfile from \"./component/recruiter/Profile\";\nimport MessagePopup from \"./lib/MessagePopup\";\nimport isAuth, { userType } from \"./lib/isAuth\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    display: \"flex\",\n    flexDirection: \"column\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n    minHeight: \"98vh\",\n    paddingTop: \"64px\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n}));\n\nexport const SetPopupContext = createContext();\n\nfunction App() {\n  const classes = useStyles();\n  const [popup, setPopup] = useState({\n    open: false,\n    severity: \"\",\n    message: \"\",\n  });\n  return (\n    <BrowserRouter>\n      <SetPopupContext.Provider value={setPopup}>\n        <Grid container direction=\"column\">\n          <Grid item xs>\n            <Navbar />\n          </Grid>\n          <Grid item className={classes.body}>\n            <Switch>\n              <Route exact path=\"/\">\n                <Welcome />\n              </Route>\n              <Route exact path=\"/login\">\n                <Login />\n              </Route>\n              <Route exact path=\"/signup\">\n                <Signup />\n              </Route>\n              <Route exact path=\"/logout\">\n                <Logout />\n              </Route>\n              <Route exact path=\"/home\">\n                <Home />\n              </Route>\n              <Route exact path=\"/applications\">\n                <Applications />\n              </Route>\n              <Route exact path=\"/profile\">\n                {userType() === \"recruiter\" ? (\n                  <RecruiterProfile />\n                ) : (\n                  <Profile />\n                )}\n              </Route>\n              <Route exact path=\"/addjob\">\n                <CreateJobs />\n              </Route>\n              <Route exact path=\"/myjobs\">\n                <MyJobs />\n              </Route>\n              <Route exact path=\"/job/applications/:jobId\">\n                <JobApplications />\n              </Route>\n              <Route exact path=\"/employees\">\n                <AcceptedApplicants />\n              </Route>\n              <Route>\n                <ErrorPage />\n              </Route>\n            </Switch>\n          </Grid>\n        </Grid>\n        <MessagePopup\n          open={popup.open}\n          setOpen={(status) =>\n            setPopup({\n              ...popup,\n              open: status,\n            })\n          }\n          severity={popup.severity}\n          message={popup.message}\n        />\n      </SetPopupContext.Provider>\n    </BrowserRouter>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "frontend/src/App.test.js",
    "content": "import { render, screen } from '@testing-library/react';\nimport App from './App';\n\ntest('renders learn react link', () => {\n  render(<App />);\n  const linkElement = screen.getByText(/learn react/i);\n  expect(linkElement).toBeInTheDocument();\n});\n"
  },
  {
    "path": "frontend/src/component/Applications.js",
    "content": "import { useState, useEffect, useContext } from \"react\";\nimport {\n  Button,\n  Chip,\n  Grid,\n  IconButton,\n  InputAdornment,\n  makeStyles,\n  Paper,\n  TextField,\n  Typography,\n  Modal,\n  Slider,\n  FormControlLabel,\n  FormGroup,\n  MenuItem,\n  Checkbox,\n} from \"@material-ui/core\";\nimport Rating from \"@material-ui/lab/Rating\";\nimport axios from \"axios\";\n\nimport { SetPopupContext } from \"../App\";\n\nimport apiList from \"../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  statusBlock: {\n    width: \"100%\",\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    textTransform: \"uppercase\",\n  },\n  jobTileOuter: {\n    padding: \"30px\",\n    margin: \"20px 0\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n}));\n\nconst ApplicationTile = (props) => {\n  const classes = useStyles();\n  const { application } = props;\n  const setPopup = useContext(SetPopupContext);\n  const [open, setOpen] = useState(false);\n  const [rating, setRating] = useState(application.job.rating);\n\n  const appliedOn = new Date(application.dateOfApplication);\n  const joinedOn = new Date(application.dateOfJoining);\n\n  const fetchRating = () => {\n    axios\n      .get(`${apiList.rating}?id=${application.job._id}`, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setRating(response.data.rating);\n        console.log(response.data);\n      })\n      .catch((err) => {\n        // console.log(err.response);\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  const changeRating = () => {\n    axios\n      .put(\n        apiList.rating,\n        { rating: rating, jobId: application.job._id },\n        {\n          headers: {\n            Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n          },\n        }\n      )\n      .then((response) => {\n        console.log(response.data);\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: \"Rating updated successfully\",\n        });\n        fetchRating();\n        setOpen(false);\n      })\n      .catch((err) => {\n        // console.log(err.response);\n        console.log(err);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        fetchRating();\n        setOpen(false);\n      });\n  };\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const colorSet = {\n    applied: \"#3454D1\",\n    shortlisted: \"#DC851F\",\n    accepted: \"#09BC8A\",\n    rejected: \"#D1345B\",\n    deleted: \"#B49A67\",\n    cancelled: \"#FF8484\",\n    finished: \"#4EA5D9\",\n  };\n\n  return (\n    <Paper className={classes.jobTileOuter} elevation={3}>\n      <Grid container>\n        <Grid container item xs={9} spacing={1} direction=\"column\">\n          <Grid item>\n            <Typography variant=\"h5\">{application.job.title}</Typography>\n          </Grid>\n          <Grid item>Posted By: {application.recruiter.name}</Grid>\n          <Grid item>Role : {application.job.jobType}</Grid>\n          <Grid item>Salary : &#8377; {application.job.salary} per month</Grid>\n          <Grid item>\n            Duration :{\" \"}\n            {application.job.duration !== 0\n              ? `${application.job.duration} month`\n              : `Flexible`}\n          </Grid>\n          <Grid item>\n            {application.job.skillsets.map((skill) => (\n              <Chip label={skill} style={{ marginRight: \"2px\" }} />\n            ))}\n          </Grid>\n          <Grid item>Applied On: {appliedOn.toLocaleDateString()}</Grid>\n          {application.status === \"accepted\" ||\n          application.status === \"finished\" ? (\n            <Grid item>Joined On: {joinedOn.toLocaleDateString()}</Grid>\n          ) : null}\n        </Grid>\n        <Grid item container direction=\"column\" xs={3}>\n          <Grid item xs>\n            <Paper\n              className={classes.statusBlock}\n              style={{\n                background: colorSet[application.status],\n                color: \"#ffffff\",\n              }}\n            >\n              {application.status}\n            </Paper>\n          </Grid>\n          {application.status === \"accepted\" ||\n          application.status === \"finished\" ? (\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"primary\"\n                className={classes.statusBlock}\n                onClick={() => {\n                  fetchRating();\n                  setOpen(true);\n                }}\n              >\n                Rate Job\n              </Button>\n            </Grid>\n          ) : null}\n        </Grid>\n      </Grid>\n      <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Rating\n            name=\"simple-controlled\"\n            style={{ marginBottom: \"30px\" }}\n            value={rating === -1 ? null : rating}\n            onChange={(event, newValue) => {\n              setRating(newValue);\n            }}\n          />\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            style={{ padding: \"10px 50px\" }}\n            onClick={() => changeRating()}\n          >\n            Submit\n          </Button>\n        </Paper>\n      </Modal>\n    </Paper>\n  );\n};\n\nconst Applications = (props) => {\n  const setPopup = useContext(SetPopupContext);\n  const [applications, setApplications] = useState([]);\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    axios\n      .get(apiList.applications, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setApplications(response.data);\n      })\n      .catch((err) => {\n        // console.log(err.response);\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  return (\n    <Grid\n      container\n      item\n      direction=\"column\"\n      alignItems=\"center\"\n      style={{ padding: \"30px\", minHeight: \"93vh\" }}\n    >\n      <Grid item>\n        <Typography variant=\"h2\">Applications</Typography>\n      </Grid>\n      <Grid\n        container\n        item\n        xs\n        direction=\"column\"\n        style={{ width: \"100%\" }}\n        alignItems=\"stretch\"\n        justify=\"center\"\n      >\n        {applications.length > 0 ? (\n          applications.map((obj) => (\n            <Grid item>\n              <ApplicationTile application={obj} />\n            </Grid>\n          ))\n        ) : (\n          <Typography variant=\"h5\" style={{ textAlign: \"center\" }}>\n            No Applications Found\n          </Typography>\n        )}\n      </Grid>\n    </Grid>\n  );\n};\n\nexport default Applications;\n"
  },
  {
    "path": "frontend/src/component/Home.js",
    "content": "import { useState, useEffect, useContext } from \"react\";\nimport {\n  Button,\n  Chip,\n  Grid,\n  IconButton,\n  InputAdornment,\n  makeStyles,\n  Paper,\n  TextField,\n  Typography,\n  Modal,\n  Slider,\n  FormControlLabel,\n  FormGroup,\n  MenuItem,\n  Checkbox,\n} from \"@material-ui/core\";\nimport Rating from \"@material-ui/lab/Rating\";\nimport Pagination from \"@material-ui/lab/Pagination\";\nimport axios from \"axios\";\nimport SearchIcon from \"@material-ui/icons/Search\";\nimport FilterListIcon from \"@material-ui/icons/FilterList\";\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\";\nimport ArrowDownwardIcon from \"@material-ui/icons/ArrowDownward\";\n\nimport { SetPopupContext } from \"../App\";\n\nimport apiList from \"../lib/apiList\";\nimport { userType } from \"../lib/isAuth\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  button: {\n    width: \"100%\",\n    height: \"100%\",\n  },\n  jobTileOuter: {\n    padding: \"30px\",\n    margin: \"20px 0\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n}));\n\nconst JobTile = (props) => {\n  const classes = useStyles();\n  const { job } = props;\n  const setPopup = useContext(SetPopupContext);\n\n  const [open, setOpen] = useState(false);\n  const [sop, setSop] = useState(\"\");\n\n  const handleClose = () => {\n    setOpen(false);\n    setSop(\"\");\n  };\n\n  const handleApply = () => {\n    console.log(job._id);\n    console.log(sop);\n    axios\n      .post(\n        `${apiList.jobs}/${job._id}/applications`,\n        {\n          sop: sop,\n        },\n        {\n          headers: {\n            Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n          },\n        }\n      )\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        handleClose();\n      })\n      .catch((err) => {\n        console.log(err.response);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        handleClose();\n      });\n  };\n\n  const deadline = new Date(job.deadline).toLocaleDateString();\n\n  return (\n    <Paper className={classes.jobTileOuter} elevation={3}>\n      <Grid container>\n        <Grid container item xs={9} spacing={1} direction=\"column\">\n          <Grid item>\n            <Typography variant=\"h5\">{job.title}</Typography>\n          </Grid>\n          <Grid item>\n            <Rating value={job.rating !== -1 ? job.rating : null} readOnly />\n          </Grid>\n          <Grid item>Role : {job.jobType}</Grid>\n          <Grid item>Salary : &#8377; {job.salary} per month</Grid>\n          <Grid item>\n            Duration :{\" \"}\n            {job.duration !== 0 ? `${job.duration} month` : `Flexible`}\n          </Grid>\n          <Grid item>Posted By : {job.recruiter.name}</Grid>\n          <Grid item>Application Deadline : {deadline}</Grid>\n\n          <Grid item>\n            {job.skillsets.map((skill) => (\n              <Chip label={skill} style={{ marginRight: \"2px\" }} />\n            ))}\n          </Grid>\n        </Grid>\n        <Grid item xs={3}>\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            className={classes.button}\n            onClick={() => {\n              setOpen(true);\n            }}\n            disabled={userType() === \"recruiter\"}\n          >\n            Apply\n          </Button>\n        </Grid>\n      </Grid>\n      <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"50%\",\n            alignItems: \"center\",\n          }}\n        >\n          <TextField\n            label=\"Write SOP (upto 250 words)\"\n            multiline\n            rows={8}\n            style={{ width: \"100%\", marginBottom: \"30px\" }}\n            variant=\"outlined\"\n            value={sop}\n            onChange={(event) => {\n              if (\n                event.target.value.split(\" \").filter(function (n) {\n                  return n != \"\";\n                }).length <= 250\n              ) {\n                setSop(event.target.value);\n              }\n            }}\n          />\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            style={{ padding: \"10px 50px\" }}\n            onClick={() => handleApply()}\n          >\n            Submit\n          </Button>\n        </Paper>\n      </Modal>\n    </Paper>\n  );\n};\n\nconst FilterPopup = (props) => {\n  const classes = useStyles();\n  const { open, handleClose, searchOptions, setSearchOptions, getData } = props;\n  return (\n    <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n      <Paper\n        style={{\n          padding: \"50px\",\n          outline: \"none\",\n          minWidth: \"50%\",\n        }}\n      >\n        <Grid container direction=\"column\" alignItems=\"center\" spacing={3}>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Job Type\n            </Grid>\n            <Grid\n              container\n              item\n              xs={9}\n              justify=\"space-around\"\n              // alignItems=\"center\"\n            >\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"fullTime\"\n                      checked={searchOptions.jobType.fullTime}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Full Time\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"partTime\"\n                      checked={searchOptions.jobType.partTime}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Part Time\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"wfh\"\n                      checked={searchOptions.jobType.wfh}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Work From Home\"\n                />\n              </Grid>\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Salary\n            </Grid>\n            <Grid item xs={9}>\n              <Slider\n                valueLabelDisplay=\"auto\"\n                valueLabelFormat={(value) => {\n                  return value * (100000 / 100);\n                }}\n                marks={[\n                  { value: 0, label: \"0\" },\n                  { value: 100, label: \"100000\" },\n                ]}\n                value={searchOptions.salary}\n                onChange={(event, value) =>\n                  setSearchOptions({\n                    ...searchOptions,\n                    salary: value,\n                  })\n                }\n              />\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Duration\n            </Grid>\n            <Grid item xs={9}>\n              <TextField\n                select\n                label=\"Duration\"\n                variant=\"outlined\"\n                fullWidth\n                value={searchOptions.duration}\n                onChange={(event) =>\n                  setSearchOptions({\n                    ...searchOptions,\n                    duration: event.target.value,\n                  })\n                }\n              >\n                <MenuItem value=\"0\">All</MenuItem>\n                <MenuItem value=\"1\">1</MenuItem>\n                <MenuItem value=\"2\">2</MenuItem>\n                <MenuItem value=\"3\">3</MenuItem>\n                <MenuItem value=\"4\">4</MenuItem>\n                <MenuItem value=\"5\">5</MenuItem>\n                <MenuItem value=\"6\">6</MenuItem>\n                <MenuItem value=\"7\">7</MenuItem>\n              </TextField>\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Sort\n            </Grid>\n            <Grid item container direction=\"row\" xs={9}>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"salary\"\n                    checked={searchOptions.sort.salary.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          salary: {\n                            ...searchOptions.sort.salary,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"salary\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"salary\">\n                    <Typography>Salary</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.salary.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          salary: {\n                            ...searchOptions.sort.salary,\n                            desc: !searchOptions.sort.salary.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.salary.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"duration\"\n                    checked={searchOptions.sort.duration.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          duration: {\n                            ...searchOptions.sort.duration,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"duration\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"duration\">\n                    <Typography>Duration</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.duration.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          duration: {\n                            ...searchOptions.sort.duration,\n                            desc: !searchOptions.sort.duration.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.duration.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"rating\"\n                    checked={searchOptions.sort.rating.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          rating: {\n                            ...searchOptions.sort.rating,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"rating\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"rating\">\n                    <Typography>Rating</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.rating.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          rating: {\n                            ...searchOptions.sort.rating,\n                            desc: !searchOptions.sort.rating.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.rating.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n            </Grid>\n          </Grid>\n\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\" }}\n              onClick={() => getData()}\n            >\n              Apply\n            </Button>\n          </Grid>\n        </Grid>\n      </Paper>\n    </Modal>\n  );\n};\n\nconst Home = (props) => {\n  const [jobs, setJobs] = useState([]);\n  const [filterOpen, setFilterOpen] = useState(false);\n  const [searchOptions, setSearchOptions] = useState({\n    query: \"\",\n    jobType: {\n      fullTime: false,\n      partTime: false,\n      wfh: false,\n    },\n    salary: [0, 100],\n    duration: \"0\",\n    sort: {\n      salary: {\n        status: false,\n        desc: false,\n      },\n      duration: {\n        status: false,\n        desc: false,\n      },\n      rating: {\n        status: false,\n        desc: false,\n      },\n    },\n  });\n\n  const setPopup = useContext(SetPopupContext);\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    let searchParams = [];\n    if (searchOptions.query !== \"\") {\n      searchParams = [...searchParams, `q=${searchOptions.query}`];\n    }\n    if (searchOptions.jobType.fullTime) {\n      searchParams = [...searchParams, `jobType=Full%20Time`];\n    }\n    if (searchOptions.jobType.partTime) {\n      searchParams = [...searchParams, `jobType=Part%20Time`];\n    }\n    if (searchOptions.jobType.wfh) {\n      searchParams = [...searchParams, `jobType=Work%20From%20Home`];\n    }\n    if (searchOptions.salary[0] != 0) {\n      searchParams = [\n        ...searchParams,\n        `salaryMin=${searchOptions.salary[0] * 1000}`,\n      ];\n    }\n    if (searchOptions.salary[1] != 100) {\n      searchParams = [\n        ...searchParams,\n        `salaryMax=${searchOptions.salary[1] * 1000}`,\n      ];\n    }\n    if (searchOptions.duration != \"0\") {\n      searchParams = [...searchParams, `duration=${searchOptions.duration}`];\n    }\n\n    let asc = [],\n      desc = [];\n\n    Object.keys(searchOptions.sort).forEach((obj) => {\n      const item = searchOptions.sort[obj];\n      if (item.status) {\n        if (item.desc) {\n          desc = [...desc, `desc=${obj}`];\n        } else {\n          asc = [...asc, `asc=${obj}`];\n        }\n      }\n    });\n    searchParams = [...searchParams, ...asc, ...desc];\n    const queryString = searchParams.join(\"&\");\n    console.log(queryString);\n    let address = apiList.jobs;\n    if (queryString !== \"\") {\n      address = `${address}?${queryString}`;\n    }\n\n    axios\n      .get(address, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setJobs(\n          response.data.filter((obj) => {\n            const today = new Date();\n            const deadline = new Date(obj.deadline);\n            return deadline > today;\n          })\n        );\n      })\n      .catch((err) => {\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid\n          item\n          container\n          direction=\"column\"\n          justify=\"center\"\n          alignItems=\"center\"\n        >\n          <Grid item xs>\n            <Typography variant=\"h2\">Jobs</Typography>\n          </Grid>\n          <Grid item xs>\n            <TextField\n              label=\"Search Jobs\"\n              value={searchOptions.query}\n              onChange={(event) =>\n                setSearchOptions({\n                  ...searchOptions,\n                  query: event.target.value,\n                })\n              }\n              onKeyPress={(ev) => {\n                if (ev.key === \"Enter\") {\n                  getData();\n                }\n              }}\n              InputProps={{\n                endAdornment: (\n                  <InputAdornment>\n                    <IconButton onClick={() => getData()}>\n                      <SearchIcon />\n                    </IconButton>\n                  </InputAdornment>\n                ),\n              }}\n              style={{ width: \"500px\" }}\n              variant=\"outlined\"\n            />\n          </Grid>\n          <Grid item>\n            <IconButton onClick={() => setFilterOpen(true)}>\n              <FilterListIcon />\n            </IconButton>\n          </Grid>\n        </Grid>\n\n        <Grid\n          container\n          item\n          xs\n          direction=\"column\"\n          alignItems=\"stretch\"\n          justify=\"center\"\n        >\n          {jobs.length > 0 ? (\n            jobs.map((job) => {\n              return <JobTile job={job} />;\n            })\n          ) : (\n            <Typography variant=\"h5\" style={{ textAlign: \"center\" }}>\n              No jobs found\n            </Typography>\n          )}\n        </Grid>\n        {/* <Grid item>\n          <Pagination count={10} color=\"primary\" />\n        </Grid> */}\n      </Grid>\n      <FilterPopup\n        open={filterOpen}\n        searchOptions={searchOptions}\n        setSearchOptions={setSearchOptions}\n        handleClose={() => setFilterOpen(false)}\n        getData={() => {\n          getData();\n          setFilterOpen(false);\n        }}\n      />\n    </>\n  );\n};\n\nexport default Home;\n"
  },
  {
    "path": "frontend/src/component/Login.js",
    "content": "import { useContext, useState } from \"react\";\nimport {\n  Grid,\n  TextField,\n  Button,\n  Typography,\n  makeStyles,\n  Paper,\n} from \"@material-ui/core\";\nimport axios from \"axios\";\nimport { Redirect } from \"react-router-dom\";\n\nimport PasswordInput from \"../lib/PasswordInput\";\nimport EmailInput from \"../lib/EmailInput\";\nimport { SetPopupContext } from \"../App\";\n\nimport apiList from \"../lib/apiList\";\nimport isAuth from \"../lib/isAuth\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    padding: \"60px 60px\",\n  },\n  inputBox: {\n    width: \"300px\",\n  },\n  submitButton: {\n    width: \"300px\",\n  },\n}));\n\nconst Login = (props) => {\n  const classes = useStyles();\n  const setPopup = useContext(SetPopupContext);\n\n  const [loggedin, setLoggedin] = useState(isAuth());\n\n  const [loginDetails, setLoginDetails] = useState({\n    email: \"\",\n    password: \"\",\n  });\n\n  const [inputErrorHandler, setInputErrorHandler] = useState({\n    email: {\n      error: false,\n      message: \"\",\n    },\n    password: {\n      error: false,\n      message: \"\",\n    },\n  });\n\n  const handleInput = (key, value) => {\n    setLoginDetails({\n      ...loginDetails,\n      [key]: value,\n    });\n  };\n\n  const handleInputError = (key, status, message) => {\n    setInputErrorHandler({\n      ...inputErrorHandler,\n      [key]: {\n        error: status,\n        message: message,\n      },\n    });\n  };\n\n  const handleLogin = () => {\n    const verified = !Object.keys(inputErrorHandler).some((obj) => {\n      return inputErrorHandler[obj].error;\n    });\n    if (verified) {\n      axios\n        .post(apiList.login, loginDetails)\n        .then((response) => {\n          localStorage.setItem(\"token\", response.data.token);\n          localStorage.setItem(\"type\", response.data.type);\n          setLoggedin(isAuth());\n          setPopup({\n            open: true,\n            severity: \"success\",\n            message: \"Logged in successfully\",\n          });\n          console.log(response);\n        })\n        .catch((err) => {\n          setPopup({\n            open: true,\n            severity: \"error\",\n            message: err.response.data.message,\n          });\n          console.log(err.response);\n        });\n    } else {\n      setPopup({\n        open: true,\n        severity: \"error\",\n        message: \"Incorrect Input\",\n      });\n    }\n  };\n\n  return loggedin ? (\n    <Redirect to=\"/\" />\n  ) : (\n    <Paper elevation={3} className={classes.body}>\n      <Grid container direction=\"column\" spacing={4} alignItems=\"center\">\n        <Grid item>\n          <Typography variant=\"h3\" component=\"h2\">\n            Login\n          </Typography>\n        </Grid>\n        <Grid item>\n          <EmailInput\n            label=\"Email\"\n            value={loginDetails.email}\n            onChange={(event) => handleInput(\"email\", event.target.value)}\n            inputErrorHandler={inputErrorHandler}\n            handleInputError={handleInputError}\n            className={classes.inputBox}\n          />\n        </Grid>\n        <Grid item>\n          <PasswordInput\n            label=\"Password\"\n            value={loginDetails.password}\n            onChange={(event) => handleInput(\"password\", event.target.value)}\n            className={classes.inputBox}\n          />\n        </Grid>\n        <Grid item>\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            onClick={() => handleLogin()}\n            className={classes.submitButton}\n          >\n            Login\n          </Button>\n        </Grid>\n      </Grid>\n    </Paper>\n  );\n};\n\nexport default Login;\n"
  },
  {
    "path": "frontend/src/component/Logout.js",
    "content": "import { useEffect, useContext } from \"react\";\nimport { Redirect } from \"react-router-dom\";\n\nimport { SetPopupContext } from \"../App\";\n\nconst Logout = (props) => {\n  const setPopup = useContext(SetPopupContext);\n  useEffect(() => {\n    localStorage.removeItem(\"token\");\n    localStorage.removeItem(\"type\");\n    setPopup({\n      open: true,\n      severity: \"success\",\n      message: \"Logged out successfully\",\n    });\n  }, []);\n  return <Redirect to=\"/login\" />;\n};\n\nexport default Logout;\n"
  },
  {
    "path": "frontend/src/component/Navbar.js",
    "content": "import {\n  AppBar,\n  Toolbar,\n  Typography,\n  Button,\n  makeStyles,\n} from \"@material-ui/core\";\nimport { useHistory } from \"react-router-dom\";\n\nimport isAuth, { userType } from \"../lib/isAuth\";\n\nconst useStyles = makeStyles((theme) => ({\n  root: {\n    flexGrow: 1,\n  },\n  menuButton: {\n    marginRight: theme.spacing(2),\n  },\n  title: {\n    flexGrow: 1,\n  },\n}));\n\nconst Navbar = (props) => {\n  const classes = useStyles();\n  let history = useHistory();\n\n  const handleClick = (location) => {\n    console.log(location);\n    history.push(location);\n  };\n\n  return (\n    <AppBar position=\"fixed\">\n      <Toolbar>\n        <Typography variant=\"h6\" className={classes.title}>\n          Job Portal\n        </Typography>\n        {isAuth() ? (\n          userType() === \"recruiter\" ? (\n            <>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/home\")}>\n                Home\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/addjob\")}>\n                Add Jobs\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/myjobs\")}>\n                My Jobs\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/employees\")}>\n                Employees\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/profile\")}>\n                Profile\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/logout\")}>\n                Logout\n              </Button>\n            </>\n          ) : (\n            <>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/home\")}>\n                Home\n              </Button>\n              <Button\n                color=\"inherit\"\n                onClick={() => handleClick(\"/applications\")}\n              >\n                Applications\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/profile\")}>\n                Profile\n              </Button>\n              <Button color=\"inherit\" onClick={() => handleClick(\"/logout\")}>\n                Logout\n              </Button>\n            </>\n          )\n        ) : (\n          <>\n            <Button color=\"inherit\" onClick={() => handleClick(\"/login\")}>\n              Login\n            </Button>\n            <Button color=\"inherit\" onClick={() => handleClick(\"/signup\")}>\n              Signup\n            </Button>\n          </>\n        )}\n      </Toolbar>\n    </AppBar>\n  );\n};\n\nexport default Navbar;\n"
  },
  {
    "path": "frontend/src/component/Profile.js",
    "content": "import { useContext, useEffect, useState } from \"react\";\nimport {\n  Button,\n  Grid,\n  Typography,\n  Modal,\n  Paper,\n  makeStyles,\n  TextField,\n} from \"@material-ui/core\";\nimport axios from \"axios\";\nimport ChipInput from \"material-ui-chip-input\";\nimport FileUploadInput from \"../lib/FileUploadInput\";\nimport DescriptionIcon from \"@material-ui/icons/Description\";\nimport FaceIcon from \"@material-ui/icons/Face\";\n\nimport { SetPopupContext } from \"../App\";\n\nimport apiList from \"../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    // padding: \"30px\",\n  },\n}));\n\nconst MultifieldInput = (props) => {\n  const classes = useStyles();\n  const { education, setEducation } = props;\n\n  return (\n    <>\n      {education.map((obj, key) => (\n        <Grid item container className={classes.inputBox} key={key}>\n          <Grid item xs={6}>\n            <TextField\n              label={`Institution Name #${key + 1}`}\n              value={education[key].institutionName}\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].institutionName = event.target.value;\n                setEducation(newEdu);\n              }}\n              variant=\"outlined\"\n              fullWidth\n            />\n          </Grid>\n          <Grid item xs={3}>\n            <TextField\n              label=\"Start Year\"\n              value={obj.startYear}\n              variant=\"outlined\"\n              type=\"number\"\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].startYear = event.target.value;\n                setEducation(newEdu);\n              }}\n            />\n          </Grid>\n          <Grid item xs={3}>\n            <TextField\n              label=\"End Year\"\n              value={obj.endYear}\n              variant=\"outlined\"\n              type=\"number\"\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].endYear = event.target.value;\n                setEducation(newEdu);\n              }}\n            />\n          </Grid>\n        </Grid>\n      ))}\n      <Grid item style={{ alignSelf: \"center\" }}>\n        <Button\n          variant=\"contained\"\n          color=\"secondary\"\n          onClick={() =>\n            setEducation([\n              ...education,\n              {\n                institutionName: \"\",\n                startYear: \"\",\n                endYear: \"\",\n              },\n            ])\n          }\n          className={classes.inputBox}\n        >\n          Add another institution details\n        </Button>\n      </Grid>\n    </>\n  );\n};\n\nconst Profile = (props) => {\n  const classes = useStyles();\n  const setPopup = useContext(SetPopupContext);\n  const [userData, setUserData] = useState();\n  const [open, setOpen] = useState(false);\n\n  const [profileDetails, setProfileDetails] = useState({\n    name: \"\",\n    education: [],\n    skills: [],\n    resume: \"\",\n    profile: \"\",\n  });\n\n  const [education, setEducation] = useState([\n    {\n      institutionName: \"\",\n      startYear: \"\",\n      endYear: \"\",\n    },\n  ]);\n\n  const handleInput = (key, value) => {\n    setProfileDetails({\n      ...profileDetails,\n      [key]: value,\n    });\n  };\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    axios\n      .get(apiList.user, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setProfileDetails(response.data);\n        if (response.data.education.length > 0) {\n          setEducation(\n            response.data.education.map((edu) => ({\n              institutionName: edu.institutionName ? edu.institutionName : \"\",\n              startYear: edu.startYear ? edu.startYear : \"\",\n              endYear: edu.endYear ? edu.endYear : \"\",\n            }))\n          );\n        }\n      })\n      .catch((err) => {\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const editDetails = () => {\n    setOpen(true);\n  };\n\n  const handleUpdate = () => {\n    console.log(education);\n\n    let updatedDetails = {\n      ...profileDetails,\n      education: education\n        .filter((obj) => obj.institutionName.trim() !== \"\")\n        .map((obj) => {\n          if (obj[\"endYear\"] === \"\") {\n            delete obj[\"endYear\"];\n          }\n          return obj;\n        }),\n    };\n\n    axios\n      .put(apiList.user, updatedDetails, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        getData();\n      })\n      .catch((err) => {\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        console.log(err.response);\n      });\n    setOpen(false);\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid item>\n          <Typography variant=\"h2\">Profile</Typography>\n        </Grid>\n        <Grid item xs>\n          <Paper\n            style={{\n              padding: \"20px\",\n              outline: \"none\",\n              display: \"flex\",\n              flexDirection: \"column\",\n              justifyContent: \"center\",\n              alignItems: \"center\",\n            }}\n          >\n            <Grid container direction=\"column\" alignItems=\"stretch\" spacing={3}>\n              <Grid item>\n                <TextField\n                  label=\"Name\"\n                  value={profileDetails.name}\n                  onChange={(event) => handleInput(\"name\", event.target.value)}\n                  className={classes.inputBox}\n                  variant=\"outlined\"\n                  fullWidth\n                />\n              </Grid>\n              <MultifieldInput\n                education={education}\n                setEducation={setEducation}\n              />\n              <Grid item>\n                <ChipInput\n                  className={classes.inputBox}\n                  label=\"Skills\"\n                  variant=\"outlined\"\n                  helperText=\"Press enter to add skills\"\n                  value={profileDetails.skills}\n                  onAdd={(chip) =>\n                    setProfileDetails({\n                      ...profileDetails,\n                      skills: [...profileDetails.skills, chip],\n                    })\n                  }\n                  onDelete={(chip, index) => {\n                    let skills = profileDetails.skills;\n                    skills.splice(index, 1);\n                    setProfileDetails({\n                      ...profileDetails,\n                      skills: skills,\n                    });\n                  }}\n                  fullWidth\n                />\n              </Grid>\n              <Grid item>\n                <FileUploadInput\n                  className={classes.inputBox}\n                  label=\"Resume (.pdf)\"\n                  icon={<DescriptionIcon />}\n                  uploadTo={apiList.uploadResume}\n                  handleInput={handleInput}\n                  identifier={\"resume\"}\n                />\n              </Grid>\n              <Grid item>\n                <FileUploadInput\n                  className={classes.inputBox}\n                  label=\"Profile Photo (.jpg/.png)\"\n                  icon={<FaceIcon />}\n                  uploadTo={apiList.uploadProfileImage}\n                  handleInput={handleInput}\n                  identifier={\"profile\"}\n                />\n              </Grid>\n            </Grid>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\", marginTop: \"30px\" }}\n              onClick={() => handleUpdate()}\n            >\n              Update Details\n            </Button>\n          </Paper>\n        </Grid>\n      </Grid>\n      {/* <Modal open={open} onClose={handleClose} className={classes.popupDialog}> */}\n\n      {/* </Modal> */}\n    </>\n  );\n};\n\nexport default Profile;\n"
  },
  {
    "path": "frontend/src/component/Signup.js",
    "content": "import { useState, useContext } from \"react\";\nimport {\n  Grid,\n  TextField,\n  Button,\n  Typography,\n  makeStyles,\n  Paper,\n  MenuItem,\n  Input,\n} from \"@material-ui/core\";\nimport axios from \"axios\";\nimport { Redirect } from \"react-router-dom\";\nimport ChipInput from \"material-ui-chip-input\";\nimport DescriptionIcon from \"@material-ui/icons/Description\";\nimport FaceIcon from \"@material-ui/icons/Face\";\nimport PhoneInput from \"react-phone-input-2\";\nimport \"react-phone-input-2/lib/material.css\";\n\nimport PasswordInput from \"../lib/PasswordInput\";\nimport EmailInput from \"../lib/EmailInput\";\nimport FileUploadInput from \"../lib/FileUploadInput\";\nimport { SetPopupContext } from \"../App\";\n\nimport apiList from \"../lib/apiList\";\nimport isAuth from \"../lib/isAuth\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    padding: \"60px 60px\",\n  },\n  inputBox: {\n    width: \"400px\",\n  },\n  submitButton: {\n    width: \"400px\",\n  },\n}));\n\nconst MultifieldInput = (props) => {\n  const classes = useStyles();\n  const { education, setEducation } = props;\n\n  return (\n    <>\n      {education.map((obj, key) => (\n        <Grid\n          item\n          container\n          className={classes.inputBox}\n          key={key}\n          style={{ paddingLeft: 0, paddingRight: 0 }}\n        >\n          <Grid item xs={6}>\n            <TextField\n              label={`Institution Name #${key + 1}`}\n              value={education[key].institutionName}\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].institutionName = event.target.value;\n                setEducation(newEdu);\n              }}\n              variant=\"outlined\"\n            />\n          </Grid>\n          <Grid item xs={3}>\n            <TextField\n              label=\"Start Year\"\n              value={obj.startYear}\n              variant=\"outlined\"\n              type=\"number\"\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].startYear = event.target.value;\n                setEducation(newEdu);\n              }}\n            />\n          </Grid>\n          <Grid item xs={3}>\n            <TextField\n              label=\"End Year\"\n              value={obj.endYear}\n              variant=\"outlined\"\n              type=\"number\"\n              onChange={(event) => {\n                const newEdu = [...education];\n                newEdu[key].endYear = event.target.value;\n                setEducation(newEdu);\n              }}\n            />\n          </Grid>\n        </Grid>\n      ))}\n      <Grid item>\n        <Button\n          variant=\"contained\"\n          color=\"secondary\"\n          onClick={() =>\n            setEducation([\n              ...education,\n              {\n                institutionName: \"\",\n                startYear: \"\",\n                endYear: \"\",\n              },\n            ])\n          }\n          className={classes.inputBox}\n        >\n          Add another institution details\n        </Button>\n      </Grid>\n    </>\n  );\n};\n\nconst Login = (props) => {\n  const classes = useStyles();\n  const setPopup = useContext(SetPopupContext);\n\n  const [loggedin, setLoggedin] = useState(isAuth());\n\n  const [signupDetails, setSignupDetails] = useState({\n    type: \"applicant\",\n    email: \"\",\n    password: \"\",\n    name: \"\",\n    education: [],\n    skills: [],\n    resume: \"\",\n    profile: \"\",\n    bio: \"\",\n    contactNumber: \"\",\n  });\n\n  const [phone, setPhone] = useState(\"\");\n\n  const [education, setEducation] = useState([\n    {\n      institutionName: \"\",\n      startYear: \"\",\n      endYear: \"\",\n    },\n  ]);\n\n  const [inputErrorHandler, setInputErrorHandler] = useState({\n    email: {\n      untouched: true,\n      required: true,\n      error: false,\n      message: \"\",\n    },\n    password: {\n      untouched: true,\n      required: true,\n      error: false,\n      message: \"\",\n    },\n    name: {\n      untouched: true,\n      required: true,\n      error: false,\n      message: \"\",\n    },\n  });\n\n  const handleInput = (key, value) => {\n    setSignupDetails({\n      ...signupDetails,\n      [key]: value,\n    });\n  };\n\n  const handleInputError = (key, status, message) => {\n    setInputErrorHandler({\n      ...inputErrorHandler,\n      [key]: {\n        required: true,\n        untouched: false,\n        error: status,\n        message: message,\n      },\n    });\n  };\n\n  const handleLogin = () => {\n    const tmpErrorHandler = {};\n    Object.keys(inputErrorHandler).forEach((obj) => {\n      if (inputErrorHandler[obj].required && inputErrorHandler[obj].untouched) {\n        tmpErrorHandler[obj] = {\n          required: true,\n          untouched: false,\n          error: true,\n          message: `${obj[0].toUpperCase() + obj.substr(1)} is required`,\n        };\n      } else {\n        tmpErrorHandler[obj] = inputErrorHandler[obj];\n      }\n    });\n\n    console.log(education);\n\n    let updatedDetails = {\n      ...signupDetails,\n      education: education\n        .filter((obj) => obj.institutionName.trim() !== \"\")\n        .map((obj) => {\n          if (obj[\"endYear\"] === \"\") {\n            delete obj[\"endYear\"];\n          }\n          return obj;\n        }),\n    };\n\n    setSignupDetails(updatedDetails);\n\n    const verified = !Object.keys(tmpErrorHandler).some((obj) => {\n      return tmpErrorHandler[obj].error;\n    });\n\n    if (verified) {\n      axios\n        .post(apiList.signup, updatedDetails)\n        .then((response) => {\n          localStorage.setItem(\"token\", response.data.token);\n          localStorage.setItem(\"type\", response.data.type);\n          setLoggedin(isAuth());\n          setPopup({\n            open: true,\n            severity: \"success\",\n            message: \"Logged in successfully\",\n          });\n          console.log(response);\n        })\n        .catch((err) => {\n          setPopup({\n            open: true,\n            severity: \"error\",\n            message: err.response.data.message,\n          });\n          console.log(err.response);\n        });\n    } else {\n      setInputErrorHandler(tmpErrorHandler);\n      setPopup({\n        open: true,\n        severity: \"error\",\n        message: \"Incorrect Input\",\n      });\n    }\n  };\n\n  const handleLoginRecruiter = () => {\n    const tmpErrorHandler = {};\n    Object.keys(inputErrorHandler).forEach((obj) => {\n      if (inputErrorHandler[obj].required && inputErrorHandler[obj].untouched) {\n        tmpErrorHandler[obj] = {\n          required: true,\n          untouched: false,\n          error: true,\n          message: `${obj[0].toUpperCase() + obj.substr(1)} is required`,\n        };\n      } else {\n        tmpErrorHandler[obj] = inputErrorHandler[obj];\n      }\n    });\n\n    let updatedDetails = {\n      ...signupDetails,\n    };\n    if (phone !== \"\") {\n      updatedDetails = {\n        ...signupDetails,\n        contactNumber: `+${phone}`,\n      };\n    } else {\n      updatedDetails = {\n        ...signupDetails,\n        contactNumber: \"\",\n      };\n    }\n\n    setSignupDetails(updatedDetails);\n\n    const verified = !Object.keys(tmpErrorHandler).some((obj) => {\n      return tmpErrorHandler[obj].error;\n    });\n\n    console.log(updatedDetails);\n\n    if (verified) {\n      axios\n        .post(apiList.signup, updatedDetails)\n        .then((response) => {\n          localStorage.setItem(\"token\", response.data.token);\n          localStorage.setItem(\"type\", response.data.type);\n          setLoggedin(isAuth());\n          setPopup({\n            open: true,\n            severity: \"success\",\n            message: \"Logged in successfully\",\n          });\n          console.log(response);\n        })\n        .catch((err) => {\n          setPopup({\n            open: true,\n            severity: \"error\",\n            message: err.response.data.message,\n          });\n          console.log(err.response);\n        });\n    } else {\n      setInputErrorHandler(tmpErrorHandler);\n      setPopup({\n        open: true,\n        severity: \"error\",\n        message: \"Incorrect Input\",\n      });\n    }\n  };\n\n  return loggedin ? (\n    <Redirect to=\"/\" />\n  ) : (\n    <Paper elevation={3} className={classes.body}>\n      <Grid container direction=\"column\" spacing={4} alignItems=\"center\">\n        <Grid item>\n          <Typography variant=\"h3\" component=\"h2\">\n            Signup\n          </Typography>\n        </Grid>\n        <Grid item>\n          <TextField\n            select\n            label=\"Category\"\n            variant=\"outlined\"\n            className={classes.inputBox}\n            value={signupDetails.type}\n            onChange={(event) => {\n              handleInput(\"type\", event.target.value);\n            }}\n          >\n            <MenuItem value=\"applicant\">Applicant</MenuItem>\n            <MenuItem value=\"recruiter\">Recruiter</MenuItem>\n          </TextField>\n        </Grid>\n        <Grid item>\n          <TextField\n            label=\"Name\"\n            value={signupDetails.name}\n            onChange={(event) => handleInput(\"name\", event.target.value)}\n            className={classes.inputBox}\n            error={inputErrorHandler.name.error}\n            helperText={inputErrorHandler.name.message}\n            onBlur={(event) => {\n              if (event.target.value === \"\") {\n                handleInputError(\"name\", true, \"Name is required\");\n              } else {\n                handleInputError(\"name\", false, \"\");\n              }\n            }}\n            variant=\"outlined\"\n          />\n        </Grid>\n        <Grid item>\n          <EmailInput\n            label=\"Email\"\n            value={signupDetails.email}\n            onChange={(event) => handleInput(\"email\", event.target.value)}\n            inputErrorHandler={inputErrorHandler}\n            handleInputError={handleInputError}\n            className={classes.inputBox}\n            required={true}\n          />\n        </Grid>\n        <Grid item>\n          <PasswordInput\n            label=\"Password\"\n            value={signupDetails.password}\n            onChange={(event) => handleInput(\"password\", event.target.value)}\n            className={classes.inputBox}\n            error={inputErrorHandler.password.error}\n            helperText={inputErrorHandler.password.message}\n            onBlur={(event) => {\n              if (event.target.value === \"\") {\n                handleInputError(\"password\", true, \"Password is required\");\n              } else {\n                handleInputError(\"password\", false, \"\");\n              }\n            }}\n          />\n        </Grid>\n        {signupDetails.type === \"applicant\" ? (\n          <>\n            <MultifieldInput\n              education={education}\n              setEducation={setEducation}\n            />\n            <Grid item>\n              <ChipInput\n                className={classes.inputBox}\n                label=\"Skills\"\n                variant=\"outlined\"\n                helperText=\"Press enter to add skills\"\n                onChange={(chips) =>\n                  setSignupDetails({ ...signupDetails, skills: chips })\n                }\n              />\n            </Grid>\n            <Grid item>\n              <FileUploadInput\n                className={classes.inputBox}\n                label=\"Resume (.pdf)\"\n                icon={<DescriptionIcon />}\n                // value={files.resume}\n                // onChange={(event) =>\n                //   setFiles({\n                //     ...files,\n                //     resume: event.target.files[0],\n                //   })\n                // }\n                uploadTo={apiList.uploadResume}\n                handleInput={handleInput}\n                identifier={\"resume\"}\n              />\n            </Grid>\n            <Grid item>\n              <FileUploadInput\n                className={classes.inputBox}\n                label=\"Profile Photo (.jpg/.png)\"\n                icon={<FaceIcon />}\n                // value={files.profileImage}\n                // onChange={(event) =>\n                //   setFiles({\n                //     ...files,\n                //     profileImage: event.target.files[0],\n                //   })\n                // }\n                uploadTo={apiList.uploadProfileImage}\n                handleInput={handleInput}\n                identifier={\"profile\"}\n              />\n            </Grid>\n          </>\n        ) : (\n          <>\n            <Grid item style={{ width: \"100%\" }}>\n              <TextField\n                label=\"Bio (upto 250 words)\"\n                multiline\n                rows={8}\n                style={{ width: \"100%\" }}\n                variant=\"outlined\"\n                value={signupDetails.bio}\n                onChange={(event) => {\n                  if (\n                    event.target.value.split(\" \").filter(function (n) {\n                      return n != \"\";\n                    }).length <= 250\n                  ) {\n                    handleInput(\"bio\", event.target.value);\n                  }\n                }}\n              />\n            </Grid>\n            <Grid item>\n              <PhoneInput\n                country={\"in\"}\n                value={phone}\n                onChange={(phone) => setPhone(phone)}\n              />\n            </Grid>\n          </>\n        )}\n\n        <Grid item>\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            onClick={() => {\n              signupDetails.type === \"applicant\"\n                ? handleLogin()\n                : handleLoginRecruiter();\n            }}\n            className={classes.submitButton}\n          >\n            Signup\n          </Button>\n        </Grid>\n      </Grid>\n    </Paper>\n  );\n};\n\nexport default Login;\n\n// {/* <Grid item>\n//           <PasswordInput\n//             label=\"Re-enter Password\"\n//             value={signupDetails.tmpPassword}\n//             onChange={(event) => handleInput(\"tmpPassword\", event.target.value)}\n//             className={classes.inputBox}\n//             labelWidth={140}\n//             helperText={inputErrorHandler.tmpPassword.message}\n//             error={inputErrorHandler.tmpPassword.error}\n//             onBlur={(event) => {\n//               if (event.target.value !== signupDetails.password) {\n//                 handleInputError(\n//                   \"tmpPassword\",\n//                   true,\n//                   \"Passwords are not same.\"\n//                 );\n//               }\n//             }}\n//           />\n//         </Grid> */}\n"
  },
  {
    "path": "frontend/src/component/Welcome.js",
    "content": "import { Grid, Typography } from \"@material-ui/core\";\n\nconst Welcome = (props) => {\n  return (\n    <Grid\n      container\n      item\n      direction=\"column\"\n      alignItems=\"center\"\n      justify=\"center\"\n      style={{ padding: \"30px\", minHeight: \"93vh\" }}\n    >\n      <Grid item>\n        <Typography variant=\"h2\">Welcome to Job Portal</Typography>\n      </Grid>\n    </Grid>\n  );\n};\n\nexport const ErrorPage = (props) => {\n  return (\n    <Grid\n      container\n      item\n      direction=\"column\"\n      alignItems=\"center\"\n      justify=\"center\"\n      style={{ padding: \"30px\", minHeight: \"93vh\" }}\n    >\n      <Grid item>\n        <Typography variant=\"h2\">Error 404</Typography>\n      </Grid>\n    </Grid>\n  );\n};\n\nexport default Welcome;\n"
  },
  {
    "path": "frontend/src/component/recruiter/AcceptedApplicants.js",
    "content": "import { useState, useEffect, useContext } from \"react\";\nimport {\n  Button,\n  Chip,\n  Grid,\n  IconButton,\n  InputAdornment,\n  makeStyles,\n  Paper,\n  TextField,\n  Typography,\n  Modal,\n  Slider,\n  FormControlLabel,\n  FormGroup,\n  MenuItem,\n  Checkbox,\n  Avatar,\n} from \"@material-ui/core\";\nimport { useParams } from \"react-router-dom\";\nimport Rating from \"@material-ui/lab/Rating\";\nimport axios from \"axios\";\nimport FilterListIcon from \"@material-ui/icons/FilterList\";\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\";\nimport ArrowDownwardIcon from \"@material-ui/icons/ArrowDownward\";\n\nimport { SetPopupContext } from \"../../App\";\n\nimport apiList, { server } from \"../../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  statusBlock: {\n    width: \"100%\",\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    textTransform: \"uppercase\",\n  },\n  jobTileOuter: {\n    padding: \"30px\",\n    margin: \"20px 0\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n  avatar: {\n    width: theme.spacing(17),\n    height: theme.spacing(17),\n  },\n}));\n\nconst FilterPopup = (props) => {\n  const classes = useStyles();\n  const { open, handleClose, searchOptions, setSearchOptions, getData } = props;\n  return (\n    <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n      <Paper\n        style={{\n          padding: \"50px\",\n          outline: \"none\",\n          minWidth: \"50%\",\n        }}\n      >\n        <Grid container direction=\"column\" alignItems=\"center\" spacing={3}>\n          {/* <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Application Status\n            </Grid>\n            <Grid\n              container\n              item\n              xs={9}\n              justify=\"space-around\"\n              // alignItems=\"center\"\n            >\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"rejected\"\n                      checked={searchOptions.status.rejected}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Rejected\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"applied\"\n                      checked={searchOptions.status.applied}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Applied\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"shortlisted\"\n                      checked={searchOptions.status.shortlisted}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Shortlisted\"\n                />\n              </Grid>\n            </Grid>\n          </Grid> */}\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Sort\n            </Grid>\n            <Grid item container direction=\"row\" xs={9}>\n              <Grid\n                item\n                container\n                xs={6}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"name\"\n                    checked={searchOptions.sort[\"jobApplicant.name\"].status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.name\": {\n                            ...searchOptions.sort[\"jobApplicant.name\"],\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"name\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"name\">\n                    <Typography>Name</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort[\"jobApplicant.name\"].status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.name\": {\n                            ...searchOptions.sort[\"jobApplicant.name\"],\n                            desc: !searchOptions.sort[\"jobApplicant.name\"].desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort[\"jobApplicant.name\"].desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={6}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"jobTitle\"\n                    checked={searchOptions.sort[\"job.title\"].status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"job.title\": {\n                            ...searchOptions.sort[\"job.title\"],\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"jobTitle\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"jobTitle\">\n                    <Typography>Job Title</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort[\"job.title\"].status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"job.title\": {\n                            ...searchOptions.sort[\"job.title\"],\n                            desc: !searchOptions.sort[\"job.title\"].desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort[\"job.title\"].desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={6}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"dateOfJoining\"\n                    checked={searchOptions.sort.dateOfJoining.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          dateOfJoining: {\n                            ...searchOptions.sort.dateOfJoining,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"dateOfJoining\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"dateOfJoining\">\n                    <Typography>Date of Joining</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.dateOfJoining.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          dateOfJoining: {\n                            ...searchOptions.sort.dateOfJoining,\n                            desc: !searchOptions.sort.dateOfJoining.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.dateOfJoining.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={6}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"rating\"\n                    checked={searchOptions.sort[\"jobApplicant.rating\"].status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.rating\": {\n                            ...searchOptions.sort[[\"jobApplicant.rating\"]],\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"rating\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"rating\">\n                    <Typography>Rating</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort[\"jobApplicant.rating\"].status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.rating\": {\n                            ...searchOptions.sort[\"jobApplicant.rating\"],\n                            desc: !searchOptions.sort[\"jobApplicant.rating\"]\n                              .desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort[\"jobApplicant.rating\"].desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n            </Grid>\n          </Grid>\n\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\" }}\n              onClick={() => getData()}\n            >\n              Apply\n            </Button>\n          </Grid>\n        </Grid>\n      </Paper>\n    </Modal>\n  );\n};\n\nconst ApplicationTile = (props) => {\n  const classes = useStyles();\n  const { application, getData } = props;\n  const setPopup = useContext(SetPopupContext);\n  const [open, setOpen] = useState(false);\n  const [openEndJob, setOpenEndJob] = useState(false);\n  const [rating, setRating] = useState(application.jobApplicant.rating);\n\n  const appliedOn = new Date(application.dateOfApplication);\n\n  const changeRating = () => {\n    axios\n      .put(\n        apiList.rating,\n        { rating: rating, applicantId: application.jobApplicant.userId },\n        {\n          headers: {\n            Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n          },\n        }\n      )\n      .then((response) => {\n        console.log(response.data);\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: \"Rating updated successfully\",\n        });\n        // fetchRating();\n        getData();\n        setOpen(false);\n      })\n      .catch((err) => {\n        // console.log(err.response);\n        console.log(err);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        // fetchRating();\n        getData();\n        setOpen(false);\n      });\n  };\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const handleCloseEndJob = () => {\n    setOpenEndJob(false);\n  };\n\n  const colorSet = {\n    applied: \"#3454D1\",\n    shortlisted: \"#DC851F\",\n    accepted: \"#09BC8A\",\n    rejected: \"#D1345B\",\n    deleted: \"#B49A67\",\n    cancelled: \"#FF8484\",\n    finished: \"#4EA5D9\",\n  };\n\n  const getResume = () => {\n    if (\n      application.jobApplicant.resume &&\n      application.jobApplicant.resume !== \"\"\n    ) {\n      const address = `${server}${application.jobApplicant.resume}`;\n      console.log(address);\n      axios(address, {\n        method: \"GET\",\n        responseType: \"blob\",\n      })\n        .then((response) => {\n          const file = new Blob([response.data], { type: \"application/pdf\" });\n          const fileURL = URL.createObjectURL(file);\n          window.open(fileURL);\n        })\n        .catch((error) => {\n          console.log(error);\n          setPopup({\n            open: true,\n            severity: \"error\",\n            message: \"Error\",\n          });\n        });\n    } else {\n      setPopup({\n        open: true,\n        severity: \"error\",\n        message: \"No resume found\",\n      });\n    }\n  };\n\n  const updateStatus = (status) => {\n    const address = `${apiList.applications}/${application._id}`;\n    const statusData = {\n      status: status,\n      dateOfJoining: new Date().toISOString(),\n    };\n    axios\n      .put(address, statusData, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        handleCloseEndJob();\n        getData();\n      })\n      .catch((err) => {\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        console.log(err.response);\n        handleCloseEndJob();\n      });\n  };\n\n  return (\n    <Paper className={classes.jobTileOuter} elevation={3}>\n      <Grid container>\n        <Grid\n          item\n          xs={2}\n          style={{\n            display: \"flex\",\n            justifyContent: \"center\",\n            alignItems: \"center\",\n          }}\n        >\n          <Avatar\n            src={`${server}${application.jobApplicant.profile}`}\n            className={classes.avatar}\n          />\n        </Grid>\n        <Grid container item xs={7} spacing={1} direction=\"column\">\n          <Grid item>\n            <Typography variant=\"h5\">\n              {application.jobApplicant.name}\n            </Typography>\n          </Grid>\n          <Grid item>\n            <Rating\n              value={\n                application.jobApplicant.rating !== -1\n                  ? application.jobApplicant.rating\n                  : null\n              }\n              readOnly\n            />\n          </Grid>\n          <Grid item>Job Title: {application.job.title}</Grid>\n          <Grid item>Role: {application.job.jobType}</Grid>\n          <Grid item>Applied On: {appliedOn.toLocaleDateString()}</Grid>\n          <Grid item>\n            SOP: {application.sop !== \"\" ? application.sop : \"Not Submitted\"}\n          </Grid>\n          <Grid item>\n            {application.jobApplicant.skills.map((skill) => (\n              <Chip label={skill} style={{ marginRight: \"2px\" }} />\n            ))}\n          </Grid>\n        </Grid>\n        <Grid item container direction=\"column\" xs={3}>\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              className={classes.statusBlock}\n              color=\"primary\"\n              onClick={() => getResume()}\n            >\n              Download Resume\n            </Button>\n          </Grid>\n          <Grid item container xs>\n            {/* {buttonSet[application.status]} */}\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              className={classes.statusBlock}\n              style={{\n                background: \"#09BC8A\",\n              }}\n              onClick={() => {\n                setOpenEndJob(true);\n              }}\n            >\n              End Job\n            </Button>\n          </Grid>\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              className={classes.statusBlock}\n              onClick={() => {\n                setOpen(true);\n              }}\n            >\n              Rate Applicant\n            </Button>\n          </Grid>\n        </Grid>\n      </Grid>\n      <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Rating\n            name=\"simple-controlled\"\n            style={{ marginBottom: \"30px\" }}\n            value={rating === -1 ? null : rating}\n            onChange={(event, newValue) => {\n              setRating(newValue);\n            }}\n          />\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            style={{ padding: \"10px 50px\" }}\n            onClick={() => changeRating()}\n          >\n            Submit\n          </Button>\n        </Paper>\n      </Modal>\n      <Modal\n        open={openEndJob}\n        onClose={handleCloseEndJob}\n        className={classes.popupDialog}\n      >\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Typography variant=\"h4\" style={{ marginBottom: \"10px\" }}>\n            Are you sure?\n          </Typography>\n          <Grid container justify=\"center\" spacing={5}>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"secondary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => {\n                  updateStatus(\"finished\");\n                }}\n              >\n                Yes\n              </Button>\n            </Grid>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"primary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => handleCloseEndJob()}\n              >\n                Cancel\n              </Button>\n            </Grid>\n          </Grid>\n        </Paper>\n      </Modal>\n    </Paper>\n  );\n};\n\nconst AcceptedApplicants = (props) => {\n  const setPopup = useContext(SetPopupContext);\n  const [applications, setApplications] = useState([]);\n  const [filterOpen, setFilterOpen] = useState(false);\n  const [searchOptions, setSearchOptions] = useState({\n    sort: {\n      \"jobApplicant.name\": {\n        status: false,\n        desc: false,\n      },\n      \"job.title\": {\n        status: false,\n        desc: false,\n      },\n      dateOfJoining: {\n        status: true,\n        desc: true,\n      },\n      \"jobApplicant.rating\": {\n        status: false,\n        desc: false,\n      },\n    },\n  });\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    let searchParams = [];\n    searchParams = [...searchParams, `status=accepted`];\n\n    let asc = [],\n      desc = [];\n\n    Object.keys(searchOptions.sort).forEach((obj) => {\n      const item = searchOptions.sort[obj];\n      if (item.status) {\n        if (item.desc) {\n          desc = [...desc, `desc=${obj}`];\n        } else {\n          asc = [...asc, `asc=${obj}`];\n        }\n      }\n    });\n\n    searchParams = [...searchParams, ...asc, ...desc];\n    const queryString = searchParams.join(\"&\");\n    console.log(queryString);\n    let address = `${apiList.applicants}`;\n    if (queryString !== \"\") {\n      address = `${address}?${queryString}`;\n    }\n\n    console.log(address);\n\n    axios\n      .get(address, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setApplications(response.data);\n      })\n      .catch((err) => {\n        console.log(err.response);\n        // console.log(err.response.data);\n        setApplications([]);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid item>\n          <Typography variant=\"h2\">Employees</Typography>\n        </Grid>\n        <Grid item>\n          <IconButton onClick={() => setFilterOpen(true)}>\n            <FilterListIcon />\n          </IconButton>\n        </Grid>\n        <Grid\n          container\n          item\n          xs\n          direction=\"column\"\n          style={{ width: \"100%\" }}\n          alignItems=\"stretch\"\n          justify=\"center\"\n        >\n          {applications.length > 0 ? (\n            applications.map((obj) => (\n              <Grid item>\n                {/* {console.log(obj)} */}\n                <ApplicationTile application={obj} getData={getData} />\n              </Grid>\n            ))\n          ) : (\n            <Typography variant=\"h5\" style={{ textAlign: \"center\" }}>\n              No Applications Found\n            </Typography>\n          )}\n        </Grid>\n      </Grid>\n      <FilterPopup\n        open={filterOpen}\n        searchOptions={searchOptions}\n        setSearchOptions={setSearchOptions}\n        handleClose={() => setFilterOpen(false)}\n        getData={() => {\n          getData();\n          setFilterOpen(false);\n        }}\n      />\n    </>\n  );\n};\n\nexport default AcceptedApplicants;\n"
  },
  {
    "path": "frontend/src/component/recruiter/CreateJobs.js",
    "content": "import { useContext, useEffect, useState } from \"react\";\nimport {\n  Button,\n  Grid,\n  Typography,\n  Modal,\n  Paper,\n  makeStyles,\n  TextField,\n  MenuItem,\n} from \"@material-ui/core\";\nimport axios from \"axios\";\nimport ChipInput from \"material-ui-chip-input\";\n\nimport { SetPopupContext } from \"../../App\";\n\nimport apiList from \"../../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    // padding: \"30px\",\n  },\n}));\n\nconst CreateJobs = (props) => {\n  const classes = useStyles();\n  const setPopup = useContext(SetPopupContext);\n\n  const [jobDetails, setJobDetails] = useState({\n    title: \"\",\n    maxApplicants: 100,\n    maxPositions: 30,\n    deadline: new Date(new Date().getTime() + 10 * 24 * 60 * 60 * 1000)\n      .toISOString()\n      .substr(0, 16),\n    skillsets: [],\n    jobType: \"Full Time\",\n    duration: 0,\n    salary: 0,\n  });\n\n  const handleInput = (key, value) => {\n    setJobDetails({\n      ...jobDetails,\n      [key]: value,\n    });\n  };\n\n  const handleUpdate = () => {\n    console.log(jobDetails);\n    axios\n      .post(apiList.jobs, jobDetails, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        setJobDetails({\n          title: \"\",\n          maxApplicants: 100,\n          maxPositions: 30,\n          deadline: new Date(new Date().getTime() + 10 * 24 * 60 * 60 * 1000)\n            .toISOString()\n            .substr(0, 16),\n          skillsets: [],\n          jobType: \"Full Time\",\n          duration: 0,\n          salary: 0,\n        });\n      })\n      .catch((err) => {\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        console.log(err.response);\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\", width: \"\" }}\n      >\n        <Grid item>\n          <Typography variant=\"h2\">Add Job</Typography>\n        </Grid>\n        <Grid item container xs direction=\"column\" justify=\"center\">\n          <Grid item>\n            <Paper\n              style={{\n                padding: \"20px\",\n                outline: \"none\",\n                display: \"flex\",\n                flexDirection: \"column\",\n                justifyContent: \"center\",\n                alignItems: \"center\",\n              }}\n            >\n              <Grid\n                container\n                direction=\"column\"\n                alignItems=\"stretch\"\n                spacing={3}\n              >\n                <Grid item>\n                  <TextField\n                    label=\"Title\"\n                    value={jobDetails.title}\n                    onChange={(event) =>\n                      handleInput(\"title\", event.target.value)\n                    }\n                    variant=\"outlined\"\n                    fullWidth\n                  />\n                </Grid>\n                <Grid item>\n                  <ChipInput\n                    className={classes.inputBox}\n                    label=\"Skills\"\n                    variant=\"outlined\"\n                    helperText=\"Press enter to add skills\"\n                    value={jobDetails.skillsets}\n                    onAdd={(chip) =>\n                      setJobDetails({\n                        ...jobDetails,\n                        skillsets: [...jobDetails.skillsets, chip],\n                      })\n                    }\n                    onDelete={(chip, index) => {\n                      let skillsets = jobDetails.skillsets;\n                      skillsets.splice(index, 1);\n                      setJobDetails({\n                        ...jobDetails,\n                        skillsets: skillsets,\n                      });\n                    }}\n                    fullWidth\n                  />\n                </Grid>\n                <Grid item>\n                  <TextField\n                    select\n                    label=\"Job Type\"\n                    variant=\"outlined\"\n                    value={jobDetails.jobType}\n                    onChange={(event) => {\n                      handleInput(\"jobType\", event.target.value);\n                    }}\n                    fullWidth\n                  >\n                    <MenuItem value=\"Full Time\">Full Time</MenuItem>\n                    <MenuItem value=\"Part Time\">Part Time</MenuItem>\n                    <MenuItem value=\"Work From Home\">Work From Home</MenuItem>\n                  </TextField>\n                </Grid>\n                <Grid item>\n                  <TextField\n                    select\n                    label=\"Duration\"\n                    variant=\"outlined\"\n                    value={jobDetails.duration}\n                    onChange={(event) => {\n                      handleInput(\"duration\", event.target.value);\n                    }}\n                    fullWidth\n                  >\n                    <MenuItem value={0}>Flexible</MenuItem>\n                    <MenuItem value={1}>1 Month</MenuItem>\n                    <MenuItem value={2}>2 Months</MenuItem>\n                    <MenuItem value={3}>3 Months</MenuItem>\n                    <MenuItem value={4}>4 Months</MenuItem>\n                    <MenuItem value={5}>5 Months</MenuItem>\n                    <MenuItem value={6}>6 Months</MenuItem>\n                  </TextField>\n                </Grid>\n                <Grid item>\n                  <TextField\n                    label=\"Salary\"\n                    type=\"number\"\n                    variant=\"outlined\"\n                    value={jobDetails.salary}\n                    onChange={(event) => {\n                      handleInput(\"salary\", event.target.value);\n                    }}\n                    InputProps={{ inputProps: { min: 0 } }}\n                    fullWidth\n                  />\n                </Grid>\n                <Grid item>\n                  <TextField\n                    label=\"Application Deadline\"\n                    type=\"datetime-local\"\n                    value={jobDetails.deadline}\n                    onChange={(event) => {\n                      handleInput(\"deadline\", event.target.value);\n                    }}\n                    InputLabelProps={{\n                      shrink: true,\n                    }}\n                    variant=\"outlined\"\n                    fullWidth\n                  />\n                </Grid>\n                <Grid item>\n                  <TextField\n                    label=\"Maximum Number Of Applicants\"\n                    type=\"number\"\n                    variant=\"outlined\"\n                    value={jobDetails.maxApplicants}\n                    onChange={(event) => {\n                      handleInput(\"maxApplicants\", event.target.value);\n                    }}\n                    InputProps={{ inputProps: { min: 1 } }}\n                    fullWidth\n                  />\n                </Grid>\n                <Grid item>\n                  <TextField\n                    label=\"Positions Available\"\n                    type=\"number\"\n                    variant=\"outlined\"\n                    value={jobDetails.maxPositions}\n                    onChange={(event) => {\n                      handleInput(\"maxPositions\", event.target.value);\n                    }}\n                    InputProps={{ inputProps: { min: 1 } }}\n                    fullWidth\n                  />\n                </Grid>\n              </Grid>\n              <Button\n                variant=\"contained\"\n                color=\"primary\"\n                style={{ padding: \"10px 50px\", marginTop: \"30px\" }}\n                onClick={() => handleUpdate()}\n              >\n                Create Job\n              </Button>\n            </Paper>\n          </Grid>\n        </Grid>\n      </Grid>\n    </>\n  );\n};\n\nexport default CreateJobs;\n"
  },
  {
    "path": "frontend/src/component/recruiter/JobApplications.js",
    "content": "import { useState, useEffect, useContext } from \"react\";\nimport {\n  Button,\n  Chip,\n  Grid,\n  IconButton,\n  InputAdornment,\n  makeStyles,\n  Paper,\n  TextField,\n  Typography,\n  Modal,\n  Slider,\n  FormControlLabel,\n  FormGroup,\n  MenuItem,\n  Checkbox,\n  Avatar,\n} from \"@material-ui/core\";\nimport { useParams } from \"react-router-dom\";\nimport Rating from \"@material-ui/lab/Rating\";\nimport axios from \"axios\";\nimport FilterListIcon from \"@material-ui/icons/FilterList\";\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\";\nimport ArrowDownwardIcon from \"@material-ui/icons/ArrowDownward\";\n\nimport { SetPopupContext } from \"../../App\";\n\nimport apiList, { server } from \"../../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  statusBlock: {\n    width: \"100%\",\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    textTransform: \"uppercase\",\n  },\n  jobTileOuter: {\n    padding: \"30px\",\n    margin: \"20px 0\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n  avatar: {\n    width: theme.spacing(17),\n    height: theme.spacing(17),\n  },\n}));\n\nconst FilterPopup = (props) => {\n  const classes = useStyles();\n  const { open, handleClose, searchOptions, setSearchOptions, getData } = props;\n  return (\n    <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n      <Paper\n        style={{\n          padding: \"50px\",\n          outline: \"none\",\n          minWidth: \"50%\",\n        }}\n      >\n        <Grid container direction=\"column\" alignItems=\"center\" spacing={3}>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Application Status\n            </Grid>\n            <Grid\n              container\n              item\n              xs={9}\n              justify=\"space-around\"\n              // alignItems=\"center\"\n            >\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"rejected\"\n                      checked={searchOptions.status.rejected}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Rejected\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"applied\"\n                      checked={searchOptions.status.applied}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Applied\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"shortlisted\"\n                      checked={searchOptions.status.shortlisted}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          status: {\n                            ...searchOptions.status,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Shortlisted\"\n                />\n              </Grid>\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Sort\n            </Grid>\n            <Grid item container direction=\"row\" xs={9}>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"name\"\n                    checked={searchOptions.sort[\"jobApplicant.name\"].status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.name\": {\n                            ...searchOptions.sort[\"jobApplicant.name\"],\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"name\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"name\">\n                    <Typography>Name</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort[\"jobApplicant.name\"].status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.name\": {\n                            ...searchOptions.sort[\"jobApplicant.name\"],\n                            desc: !searchOptions.sort[\"jobApplicant.name\"].desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort[\"jobApplicant.name\"].desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"dateOfApplication\"\n                    checked={searchOptions.sort.dateOfApplication.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          dateOfApplication: {\n                            ...searchOptions.sort.dateOfApplication,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"dateOfApplication\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"dateOfApplication\">\n                    <Typography>Date of Application</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.dateOfApplication.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          dateOfApplication: {\n                            ...searchOptions.sort.dateOfApplication,\n                            desc: !searchOptions.sort.dateOfApplication.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.dateOfApplication.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"rating\"\n                    checked={searchOptions.sort[\"jobApplicant.rating\"].status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.rating\": {\n                            ...searchOptions.sort[[\"jobApplicant.rating\"]],\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"rating\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"rating\">\n                    <Typography>Rating</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort[\"jobApplicant.rating\"].status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          \"jobApplicant.rating\": {\n                            ...searchOptions.sort[\"jobApplicant.rating\"],\n                            desc: !searchOptions.sort[\"jobApplicant.rating\"]\n                              .desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort[\"jobApplicant.rating\"].desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n            </Grid>\n          </Grid>\n\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\" }}\n              onClick={() => getData()}\n            >\n              Apply\n            </Button>\n          </Grid>\n        </Grid>\n      </Paper>\n    </Modal>\n  );\n};\n\nconst ApplicationTile = (props) => {\n  const classes = useStyles();\n  const { application, getData } = props;\n  const setPopup = useContext(SetPopupContext);\n  const [open, setOpen] = useState(false);\n\n  const appliedOn = new Date(application.dateOfApplication);\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const colorSet = {\n    applied: \"#3454D1\",\n    shortlisted: \"#DC851F\",\n    accepted: \"#09BC8A\",\n    rejected: \"#D1345B\",\n    deleted: \"#B49A67\",\n    cancelled: \"#FF8484\",\n    finished: \"#4EA5D9\",\n  };\n\n  const getResume = () => {\n    if (\n      application.jobApplicant.resume &&\n      application.jobApplicant.resume !== \"\"\n    ) {\n      const address = `${server}${application.jobApplicant.resume}`;\n      console.log(address);\n      axios(address, {\n        method: \"GET\",\n        responseType: \"blob\",\n      })\n        .then((response) => {\n          const file = new Blob([response.data], { type: \"application/pdf\" });\n          const fileURL = URL.createObjectURL(file);\n          window.open(fileURL);\n        })\n        .catch((error) => {\n          console.log(error);\n          setPopup({\n            open: true,\n            severity: \"error\",\n            message: \"Error\",\n          });\n        });\n    } else {\n      setPopup({\n        open: true,\n        severity: \"error\",\n        message: \"No resume found\",\n      });\n    }\n  };\n\n  const updateStatus = (status) => {\n    const address = `${apiList.applications}/${application._id}`;\n    const statusData = {\n      status: status,\n      dateOfJoining: new Date().toISOString(),\n    };\n    axios\n      .put(address, statusData, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        getData();\n      })\n      .catch((err) => {\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        console.log(err.response);\n      });\n  };\n\n  const buttonSet = {\n    applied: (\n      <>\n        <Grid item xs>\n          <Button\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"shortlisted\"],\n              color: \"#ffffff\",\n            }}\n            onClick={() => updateStatus(\"shortlisted\")}\n          >\n            Shortlist\n          </Button>\n        </Grid>\n        <Grid item xs>\n          <Button\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"rejected\"],\n              color: \"#ffffff\",\n            }}\n            onClick={() => updateStatus(\"rejected\")}\n          >\n            Reject\n          </Button>\n        </Grid>\n      </>\n    ),\n    shortlisted: (\n      <>\n        <Grid item xs>\n          <Button\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"accepted\"],\n              color: \"#ffffff\",\n            }}\n            onClick={() => updateStatus(\"accepted\")}\n          >\n            Accept\n          </Button>\n        </Grid>\n        <Grid item xs>\n          <Button\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"rejected\"],\n              color: \"#ffffff\",\n            }}\n            onClick={() => updateStatus(\"rejected\")}\n          >\n            Reject\n          </Button>\n        </Grid>\n      </>\n    ),\n    rejected: (\n      <>\n        <Grid item xs>\n          <Paper\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"rejected\"],\n              color: \"#ffffff\",\n            }}\n          >\n            Rejected\n          </Paper>\n        </Grid>\n      </>\n    ),\n    accepted: (\n      <>\n        <Grid item xs>\n          <Paper\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"accepted\"],\n              color: \"#ffffff\",\n            }}\n          >\n            Accepted\n          </Paper>\n        </Grid>\n      </>\n    ),\n    cancelled: (\n      <>\n        <Grid item xs>\n          <Paper\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"cancelled\"],\n              color: \"#ffffff\",\n            }}\n          >\n            Cancelled\n          </Paper>\n        </Grid>\n      </>\n    ),\n    finished: (\n      <>\n        <Grid item xs>\n          <Paper\n            className={classes.statusBlock}\n            style={{\n              background: colorSet[\"finished\"],\n              color: \"#ffffff\",\n            }}\n          >\n            Finished\n          </Paper>\n        </Grid>\n      </>\n    ),\n  };\n\n  return (\n    <Paper className={classes.jobTileOuter} elevation={3}>\n      <Grid container>\n        <Grid\n          item\n          xs={2}\n          style={{\n            display: \"flex\",\n            justifyContent: \"center\",\n            alignItems: \"center\",\n          }}\n        >\n          <Avatar\n            src={`${server}${application.jobApplicant.profile}`}\n            className={classes.avatar}\n          />\n        </Grid>\n        <Grid container item xs={7} spacing={1} direction=\"column\">\n          <Grid item>\n            <Typography variant=\"h5\">\n              {application.jobApplicant.name}\n            </Typography>\n          </Grid>\n          <Grid item>\n            <Rating\n              value={\n                application.jobApplicant.rating !== -1\n                  ? application.jobApplicant.rating\n                  : null\n              }\n              readOnly\n            />\n          </Grid>\n          <Grid item>Applied On: {appliedOn.toLocaleDateString()}</Grid>\n          <Grid item>\n            Education:{\" \"}\n            {application.jobApplicant.education\n              .map((edu) => {\n                return `${edu.institutionName} (${edu.startYear}-${\n                  edu.endYear ? edu.endYear : \"Ongoing\"\n                })`;\n              })\n              .join(\", \")}\n          </Grid>\n          <Grid item>\n            SOP: {application.sop !== \"\" ? application.sop : \"Not Submitted\"}\n          </Grid>\n          <Grid item>\n            {application.jobApplicant.skills.map((skill) => (\n              <Chip label={skill} style={{ marginRight: \"2px\" }} />\n            ))}\n          </Grid>\n        </Grid>\n        <Grid item container direction=\"column\" xs={3}>\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              className={classes.statusBlock}\n              color=\"primary\"\n              onClick={() => getResume()}\n            >\n              Download Resume\n            </Button>\n          </Grid>\n          <Grid item container xs>\n            {buttonSet[application.status]}\n          </Grid>\n        </Grid>\n      </Grid>\n      <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            style={{ padding: \"10px 50px\" }}\n            // onClick={() => changeRating()}\n          >\n            Submit\n          </Button>\n        </Paper>\n      </Modal>\n    </Paper>\n  );\n};\n\nconst JobApplications = (props) => {\n  const setPopup = useContext(SetPopupContext);\n  const [applications, setApplications] = useState([]);\n  const { jobId } = useParams();\n  const [filterOpen, setFilterOpen] = useState(false);\n  const [searchOptions, setSearchOptions] = useState({\n    status: {\n      all: false,\n      applied: false,\n      shortlisted: false,\n    },\n    sort: {\n      \"jobApplicant.name\": {\n        status: false,\n        desc: false,\n      },\n      dateOfApplication: {\n        status: true,\n        desc: true,\n      },\n      \"jobApplicant.rating\": {\n        status: false,\n        desc: false,\n      },\n    },\n  });\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    let searchParams = [];\n\n    if (searchOptions.status.rejected) {\n      searchParams = [...searchParams, `status=rejected`];\n    }\n    if (searchOptions.status.applied) {\n      searchParams = [...searchParams, `status=applied`];\n    }\n    if (searchOptions.status.shortlisted) {\n      searchParams = [...searchParams, `status=shortlisted`];\n    }\n\n    let asc = [],\n      desc = [];\n\n    Object.keys(searchOptions.sort).forEach((obj) => {\n      const item = searchOptions.sort[obj];\n      if (item.status) {\n        if (item.desc) {\n          desc = [...desc, `desc=${obj}`];\n        } else {\n          asc = [...asc, `asc=${obj}`];\n        }\n      }\n    });\n    searchParams = [...searchParams, ...asc, ...desc];\n    const queryString = searchParams.join(\"&\");\n    console.log(queryString);\n    let address = `${apiList.applicants}?jobId=${jobId}`;\n    if (queryString !== \"\") {\n      address = `${address}&${queryString}`;\n    }\n\n    console.log(address);\n\n    axios\n      .get(address, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setApplications(response.data);\n      })\n      .catch((err) => {\n        console.log(err.response);\n        // console.log(err.response.data);\n        setApplications([]);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid item>\n          <Typography variant=\"h2\">Applications</Typography>\n        </Grid>\n        <Grid item>\n          <IconButton onClick={() => setFilterOpen(true)}>\n            <FilterListIcon />\n          </IconButton>\n        </Grid>\n        <Grid\n          container\n          item\n          xs\n          direction=\"column\"\n          style={{ width: \"100%\" }}\n          alignItems=\"stretch\"\n          justify=\"center\"\n        >\n          {applications.length > 0 ? (\n            applications.map((obj) => (\n              <Grid item>\n                {/* {console.log(obj)} */}\n                <ApplicationTile application={obj} getData={getData} />\n              </Grid>\n            ))\n          ) : (\n            <Typography variant=\"h5\" style={{ textAlign: \"center\" }}>\n              No Applications Found\n            </Typography>\n          )}\n        </Grid>\n      </Grid>\n      <FilterPopup\n        open={filterOpen}\n        searchOptions={searchOptions}\n        setSearchOptions={setSearchOptions}\n        handleClose={() => setFilterOpen(false)}\n        getData={() => {\n          getData();\n          setFilterOpen(false);\n        }}\n      />\n    </>\n  );\n};\n\nexport default JobApplications;\n"
  },
  {
    "path": "frontend/src/component/recruiter/MyJobs.js",
    "content": "import { useState, useEffect, useContext } from \"react\";\nimport {\n  Button,\n  Chip,\n  Grid,\n  IconButton,\n  InputAdornment,\n  makeStyles,\n  Paper,\n  TextField,\n  Typography,\n  Modal,\n  Slider,\n  FormControlLabel,\n  FormGroup,\n  MenuItem,\n  Checkbox,\n} from \"@material-ui/core\";\nimport { useHistory } from \"react-router-dom\";\nimport Rating from \"@material-ui/lab/Rating\";\nimport Pagination from \"@material-ui/lab/Pagination\";\nimport axios from \"axios\";\nimport SearchIcon from \"@material-ui/icons/Search\";\nimport FilterListIcon from \"@material-ui/icons/FilterList\";\nimport ArrowUpwardIcon from \"@material-ui/icons/ArrowUpward\";\nimport ArrowDownwardIcon from \"@material-ui/icons/ArrowDownward\";\n\nimport { SetPopupContext } from \"../../App\";\n\nimport apiList from \"../../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  button: {\n    width: \"100%\",\n    height: \"100%\",\n  },\n  jobTileOuter: {\n    padding: \"30px\",\n    margin: \"20px 0\",\n    boxSizing: \"border-box\",\n    width: \"100%\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n  },\n  statusBlock: {\n    width: \"100%\",\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    textTransform: \"uppercase\",\n  },\n}));\n\nconst JobTile = (props) => {\n  const classes = useStyles();\n  let history = useHistory();\n  const { job, getData } = props;\n  const setPopup = useContext(SetPopupContext);\n\n  const [open, setOpen] = useState(false);\n  const [openUpdate, setOpenUpdate] = useState(false);\n  const [jobDetails, setJobDetails] = useState(job);\n\n  console.log(jobDetails);\n\n  const handleInput = (key, value) => {\n    setJobDetails({\n      ...jobDetails,\n      [key]: value,\n    });\n  };\n\n  const handleClick = (location) => {\n    history.push(location);\n  };\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const handleCloseUpdate = () => {\n    setOpenUpdate(false);\n  };\n\n  const handleDelete = () => {\n    console.log(job._id);\n    axios\n      .delete(`${apiList.jobs}/${job._id}`, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        getData();\n        handleClose();\n      })\n      .catch((err) => {\n        console.log(err.response);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        handleClose();\n      });\n  };\n\n  const handleJobUpdate = () => {\n    axios\n      .put(`${apiList.jobs}/${job._id}`, jobDetails, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        getData();\n        handleCloseUpdate();\n      })\n      .catch((err) => {\n        console.log(err.response);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        handleCloseUpdate();\n      });\n  };\n\n  const postedOn = new Date(job.dateOfPosting);\n\n  return (\n    <Paper className={classes.jobTileOuter} elevation={3}>\n      <Grid container>\n        <Grid container item xs={9} spacing={1} direction=\"column\">\n          <Grid item>\n            <Typography variant=\"h5\">{job.title}</Typography>\n          </Grid>\n          <Grid item>\n            <Rating value={job.rating !== -1 ? job.rating : null} readOnly />\n          </Grid>\n          <Grid item>Role : {job.jobType}</Grid>\n          <Grid item>Salary : &#8377; {job.salary} per month</Grid>\n          <Grid item>\n            Duration :{\" \"}\n            {job.duration !== 0 ? `${job.duration} month` : `Flexible`}\n          </Grid>\n          <Grid item>Date Of Posting: {postedOn.toLocaleDateString()}</Grid>\n          <Grid item>Number of Applicants: {job.maxApplicants}</Grid>\n          <Grid item>\n            Remaining Number of Positions:{\" \"}\n            {job.maxPositions - job.acceptedCandidates}\n          </Grid>\n          <Grid item>\n            {job.skillsets.map((skill) => (\n              <Chip label={skill} style={{ marginRight: \"2px\" }} />\n            ))}\n          </Grid>\n        </Grid>\n        <Grid item container direction=\"column\" xs={3}>\n          <Grid item xs>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              className={classes.statusBlock}\n              onClick={() => handleClick(`/job/applications/${job._id}`)}\n            >\n              View Applications\n            </Button>\n          </Grid>\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              className={classes.statusBlock}\n              onClick={() => {\n                setOpenUpdate(true);\n              }}\n              style={{\n                background: \"#FC7A1E\",\n                color: \"#fff\",\n              }}\n            >\n              Update Details\n            </Button>\n          </Grid>\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"secondary\"\n              className={classes.statusBlock}\n              onClick={() => {\n                setOpen(true);\n              }}\n            >\n              Delete Job\n            </Button>\n          </Grid>\n        </Grid>\n      </Grid>\n      <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Typography variant=\"h4\" style={{ marginBottom: \"10px\" }}>\n            Are you sure?\n          </Typography>\n          <Grid container justify=\"center\" spacing={5}>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"secondary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => handleDelete()}\n              >\n                Delete\n              </Button>\n            </Grid>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"primary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => handleClose()}\n              >\n                Cancel\n              </Button>\n            </Grid>\n          </Grid>\n        </Paper>\n      </Modal>\n      <Modal\n        open={openUpdate}\n        onClose={handleCloseUpdate}\n        className={classes.popupDialog}\n      >\n        <Paper\n          style={{\n            padding: \"20px\",\n            outline: \"none\",\n            display: \"flex\",\n            flexDirection: \"column\",\n            justifyContent: \"center\",\n            minWidth: \"30%\",\n            alignItems: \"center\",\n          }}\n        >\n          <Typography variant=\"h4\" style={{ marginBottom: \"10px\" }}>\n            Update Details\n          </Typography>\n          <Grid\n            container\n            direction=\"column\"\n            spacing={3}\n            style={{ margin: \"10px\" }}\n          >\n            <Grid item>\n              <TextField\n                label=\"Application Deadline\"\n                type=\"datetime-local\"\n                value={jobDetails.deadline.substr(0, 16)}\n                onChange={(event) => {\n                  handleInput(\"deadline\", event.target.value);\n                }}\n                InputLabelProps={{\n                  shrink: true,\n                }}\n                variant=\"outlined\"\n                fullWidth\n              />\n            </Grid>\n            <Grid item>\n              <TextField\n                label=\"Maximum Number Of Applicants\"\n                type=\"number\"\n                variant=\"outlined\"\n                value={jobDetails.maxApplicants}\n                onChange={(event) => {\n                  handleInput(\"maxApplicants\", event.target.value);\n                }}\n                InputProps={{ inputProps: { min: 1 } }}\n                fullWidth\n              />\n            </Grid>\n            <Grid item>\n              <TextField\n                label=\"Positions Available\"\n                type=\"number\"\n                variant=\"outlined\"\n                value={jobDetails.maxPositions}\n                onChange={(event) => {\n                  handleInput(\"maxPositions\", event.target.value);\n                }}\n                InputProps={{ inputProps: { min: 1 } }}\n                fullWidth\n              />\n            </Grid>\n          </Grid>\n          <Grid container justify=\"center\" spacing={5}>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"secondary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => handleJobUpdate()}\n              >\n                Update\n              </Button>\n            </Grid>\n            <Grid item>\n              <Button\n                variant=\"contained\"\n                color=\"primary\"\n                style={{ padding: \"10px 50px\" }}\n                onClick={() => handleCloseUpdate()}\n              >\n                Cancel\n              </Button>\n            </Grid>\n          </Grid>\n        </Paper>\n      </Modal>\n    </Paper>\n  );\n};\n\nconst FilterPopup = (props) => {\n  const classes = useStyles();\n  const { open, handleClose, searchOptions, setSearchOptions, getData } = props;\n  return (\n    <Modal open={open} onClose={handleClose} className={classes.popupDialog}>\n      <Paper\n        style={{\n          padding: \"50px\",\n          outline: \"none\",\n          minWidth: \"50%\",\n        }}\n      >\n        <Grid container direction=\"column\" alignItems=\"center\" spacing={3}>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Job Type\n            </Grid>\n            <Grid\n              container\n              item\n              xs={9}\n              justify=\"space-around\"\n              // alignItems=\"center\"\n            >\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"fullTime\"\n                      checked={searchOptions.jobType.fullTime}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Full Time\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"partTime\"\n                      checked={searchOptions.jobType.partTime}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Part Time\"\n                />\n              </Grid>\n              <Grid item>\n                <FormControlLabel\n                  control={\n                    <Checkbox\n                      name=\"wfh\"\n                      checked={searchOptions.jobType.wfh}\n                      onChange={(event) => {\n                        setSearchOptions({\n                          ...searchOptions,\n                          jobType: {\n                            ...searchOptions.jobType,\n                            [event.target.name]: event.target.checked,\n                          },\n                        });\n                      }}\n                    />\n                  }\n                  label=\"Work From Home\"\n                />\n              </Grid>\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Salary\n            </Grid>\n            <Grid item xs={9}>\n              <Slider\n                valueLabelDisplay=\"auto\"\n                valueLabelFormat={(value) => {\n                  return value * (100000 / 100);\n                }}\n                marks={[\n                  { value: 0, label: \"0\" },\n                  { value: 100, label: \"100000\" },\n                ]}\n                value={searchOptions.salary}\n                onChange={(event, value) =>\n                  setSearchOptions({\n                    ...searchOptions,\n                    salary: value,\n                  })\n                }\n              />\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Duration\n            </Grid>\n            <Grid item xs={9}>\n              <TextField\n                select\n                label=\"Duration\"\n                variant=\"outlined\"\n                fullWidth\n                value={searchOptions.duration}\n                onChange={(event) =>\n                  setSearchOptions({\n                    ...searchOptions,\n                    duration: event.target.value,\n                  })\n                }\n              >\n                <MenuItem value=\"0\">All</MenuItem>\n                <MenuItem value=\"1\">1</MenuItem>\n                <MenuItem value=\"2\">2</MenuItem>\n                <MenuItem value=\"3\">3</MenuItem>\n                <MenuItem value=\"4\">4</MenuItem>\n                <MenuItem value=\"5\">5</MenuItem>\n                <MenuItem value=\"6\">6</MenuItem>\n                <MenuItem value=\"7\">7</MenuItem>\n              </TextField>\n            </Grid>\n          </Grid>\n          <Grid container item alignItems=\"center\">\n            <Grid item xs={3}>\n              Sort\n            </Grid>\n            <Grid item container direction=\"row\" xs={9}>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"salary\"\n                    checked={searchOptions.sort.salary.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          salary: {\n                            ...searchOptions.sort.salary,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"salary\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"salary\">\n                    <Typography>Salary</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.salary.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          salary: {\n                            ...searchOptions.sort.salary,\n                            desc: !searchOptions.sort.salary.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.salary.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"duration\"\n                    checked={searchOptions.sort.duration.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          duration: {\n                            ...searchOptions.sort.duration,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"duration\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"duration\">\n                    <Typography>Duration</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.duration.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          duration: {\n                            ...searchOptions.sort.duration,\n                            desc: !searchOptions.sort.duration.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.duration.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n              <Grid\n                item\n                container\n                xs={4}\n                justify=\"space-around\"\n                alignItems=\"center\"\n                style={{ border: \"1px solid #D1D1D1\", borderRadius: \"5px\" }}\n              >\n                <Grid item>\n                  <Checkbox\n                    name=\"rating\"\n                    checked={searchOptions.sort.rating.status}\n                    onChange={(event) =>\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          rating: {\n                            ...searchOptions.sort.rating,\n                            status: event.target.checked,\n                          },\n                        },\n                      })\n                    }\n                    id=\"rating\"\n                  />\n                </Grid>\n                <Grid item>\n                  <label for=\"rating\">\n                    <Typography>Rating</Typography>\n                  </label>\n                </Grid>\n                <Grid item>\n                  <IconButton\n                    disabled={!searchOptions.sort.rating.status}\n                    onClick={() => {\n                      setSearchOptions({\n                        ...searchOptions,\n                        sort: {\n                          ...searchOptions.sort,\n                          rating: {\n                            ...searchOptions.sort.rating,\n                            desc: !searchOptions.sort.rating.desc,\n                          },\n                        },\n                      });\n                    }}\n                  >\n                    {searchOptions.sort.rating.desc ? (\n                      <ArrowDownwardIcon />\n                    ) : (\n                      <ArrowUpwardIcon />\n                    )}\n                  </IconButton>\n                </Grid>\n              </Grid>\n            </Grid>\n          </Grid>\n\n          <Grid item>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\" }}\n              onClick={() => getData()}\n            >\n              Apply\n            </Button>\n          </Grid>\n        </Grid>\n      </Paper>\n    </Modal>\n  );\n};\n\nconst MyJobs = (props) => {\n  const [jobs, setJobs] = useState([]);\n  const [filterOpen, setFilterOpen] = useState(false);\n  const [searchOptions, setSearchOptions] = useState({\n    query: \"\",\n    jobType: {\n      fullTime: false,\n      partTime: false,\n      wfh: false,\n    },\n    salary: [0, 100],\n    duration: \"0\",\n    sort: {\n      salary: {\n        status: false,\n        desc: false,\n      },\n      duration: {\n        status: false,\n        desc: false,\n      },\n      rating: {\n        status: false,\n        desc: false,\n      },\n    },\n  });\n\n  const setPopup = useContext(SetPopupContext);\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    let searchParams = [`myjobs=1`];\n    if (searchOptions.query !== \"\") {\n      searchParams = [...searchParams, `q=${searchOptions.query}`];\n    }\n    if (searchOptions.jobType.fullTime) {\n      searchParams = [...searchParams, `jobType=Full%20Time`];\n    }\n    if (searchOptions.jobType.partTime) {\n      searchParams = [...searchParams, `jobType=Part%20Time`];\n    }\n    if (searchOptions.jobType.wfh) {\n      searchParams = [...searchParams, `jobType=Work%20From%20Home`];\n    }\n    if (searchOptions.salary[0] != 0) {\n      searchParams = [\n        ...searchParams,\n        `salaryMin=${searchOptions.salary[0] * 1000}`,\n      ];\n    }\n    if (searchOptions.salary[1] != 100) {\n      searchParams = [\n        ...searchParams,\n        `salaryMax=${searchOptions.salary[1] * 1000}`,\n      ];\n    }\n    if (searchOptions.duration != \"0\") {\n      searchParams = [...searchParams, `duration=${searchOptions.duration}`];\n    }\n\n    let asc = [],\n      desc = [];\n\n    Object.keys(searchOptions.sort).forEach((obj) => {\n      const item = searchOptions.sort[obj];\n      if (item.status) {\n        if (item.desc) {\n          desc = [...desc, `desc=${obj}`];\n        } else {\n          asc = [...asc, `asc=${obj}`];\n        }\n      }\n    });\n    searchParams = [...searchParams, ...asc, ...desc];\n    const queryString = searchParams.join(\"&\");\n    console.log(queryString);\n    let address = apiList.jobs;\n    if (queryString !== \"\") {\n      address = `${address}?${queryString}`;\n    }\n\n    console.log(address);\n    axios\n      .get(address, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setJobs(response.data);\n      })\n      .catch((err) => {\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid\n          item\n          container\n          direction=\"column\"\n          justify=\"center\"\n          alignItems=\"center\"\n        >\n          <Grid item xs>\n            <Typography variant=\"h2\">My Jobs</Typography>\n          </Grid>\n          <Grid item xs>\n            <TextField\n              label=\"Search Jobs\"\n              value={searchOptions.query}\n              onChange={(event) =>\n                setSearchOptions({\n                  ...searchOptions,\n                  query: event.target.value,\n                })\n              }\n              onKeyPress={(ev) => {\n                if (ev.key === \"Enter\") {\n                  getData();\n                }\n              }}\n              InputProps={{\n                endAdornment: (\n                  <InputAdornment>\n                    <IconButton onClick={() => getData()}>\n                      <SearchIcon />\n                    </IconButton>\n                  </InputAdornment>\n                ),\n              }}\n              style={{ width: \"500px\" }}\n              variant=\"outlined\"\n            />\n          </Grid>\n          <Grid item>\n            <IconButton onClick={() => setFilterOpen(true)}>\n              <FilterListIcon />\n            </IconButton>\n          </Grid>\n        </Grid>\n\n        <Grid\n          container\n          item\n          xs\n          direction=\"column\"\n          alignItems=\"stretch\"\n          justify=\"center\"\n        >\n          {jobs.length > 0 ? (\n            jobs.map((job) => {\n              return <JobTile job={job} getData={getData} />;\n            })\n          ) : (\n            <Typography variant=\"h5\" style={{ textAlign: \"center\" }}>\n              No jobs found\n            </Typography>\n          )}\n        </Grid>\n      </Grid>\n      <FilterPopup\n        open={filterOpen}\n        searchOptions={searchOptions}\n        setSearchOptions={setSearchOptions}\n        handleClose={() => setFilterOpen(false)}\n        getData={() => {\n          getData();\n          setFilterOpen(false);\n        }}\n      />\n    </>\n  );\n};\n\nexport default MyJobs;\n"
  },
  {
    "path": "frontend/src/component/recruiter/Profile.js",
    "content": "import { useContext, useEffect, useState } from \"react\";\nimport {\n  Button,\n  Grid,\n  Typography,\n  Modal,\n  Paper,\n  makeStyles,\n  TextField,\n} from \"@material-ui/core\";\nimport axios from \"axios\";\nimport PhoneInput from \"react-phone-input-2\";\nimport \"react-phone-input-2/lib/material.css\";\n\nimport { SetPopupContext } from \"../../App\";\n\nimport apiList from \"../../lib/apiList\";\n\nconst useStyles = makeStyles((theme) => ({\n  body: {\n    height: \"inherit\",\n  },\n  popupDialog: {\n    height: \"100%\",\n    display: \"flex\",\n    alignItems: \"center\",\n    justifyContent: \"center\",\n    // padding: \"30px\",\n  },\n}));\n\nconst Profile = (props) => {\n  const classes = useStyles();\n  const setPopup = useContext(SetPopupContext);\n\n  const [profileDetails, setProfileDetails] = useState({\n    name: \"\",\n    bio: \"\",\n    contactNumber: \"\",\n  });\n\n  const [phone, setPhone] = useState(\"\");\n\n  const handleInput = (key, value) => {\n    setProfileDetails({\n      ...profileDetails,\n      [key]: value,\n    });\n  };\n\n  useEffect(() => {\n    getData();\n  }, []);\n\n  const getData = () => {\n    axios\n      .get(apiList.user, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        console.log(response.data);\n        setProfileDetails(response.data);\n        setPhone(response.data.contactNumber);\n      })\n      .catch((err) => {\n        console.log(err.response.data);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: \"Error\",\n        });\n      });\n  };\n\n  const handleUpdate = () => {\n    let updatedDetails = {\n      ...profileDetails,\n    };\n    if (phone !== \"\") {\n      updatedDetails = {\n        ...profileDetails,\n        contactNumber: `+${phone}`,\n      };\n    } else {\n      updatedDetails = {\n        ...profileDetails,\n        contactNumber: \"\",\n      };\n    }\n\n    axios\n      .put(apiList.user, updatedDetails, {\n        headers: {\n          Authorization: `Bearer ${localStorage.getItem(\"token\")}`,\n        },\n      })\n      .then((response) => {\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n        getData();\n      })\n      .catch((err) => {\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.data.message,\n        });\n        console.log(err.response);\n      });\n  };\n\n  return (\n    <>\n      <Grid\n        container\n        item\n        direction=\"column\"\n        alignItems=\"center\"\n        style={{ padding: \"30px\", minHeight: \"93vh\" }}\n      >\n        <Grid item>\n          <Typography variant=\"h2\">Profile</Typography>\n        </Grid>\n        <Grid item xs style={{ width: \"100%\" }}>\n          <Paper\n            style={{\n              padding: \"20px\",\n              outline: \"none\",\n              display: \"flex\",\n              flexDirection: \"column\",\n              justifyContent: \"center\",\n              alignItems: \"center\",\n              //   width: \"60%\",\n            }}\n          >\n            <Grid container direction=\"column\" alignItems=\"stretch\" spacing={3}>\n              <Grid item>\n                <TextField\n                  label=\"Name\"\n                  value={profileDetails.name}\n                  onChange={(event) => handleInput(\"name\", event.target.value)}\n                  className={classes.inputBox}\n                  variant=\"outlined\"\n                  fullWidth\n                  style={{ width: \"100%\" }}\n                />\n              </Grid>\n              <Grid item>\n                <TextField\n                  label=\"Bio (upto 250 words)\"\n                  multiline\n                  rows={8}\n                  style={{ width: \"100%\" }}\n                  variant=\"outlined\"\n                  value={profileDetails.bio}\n                  onChange={(event) => {\n                    if (\n                      event.target.value.split(\" \").filter(function (n) {\n                        return n != \"\";\n                      }).length <= 250\n                    ) {\n                      handleInput(\"bio\", event.target.value);\n                    }\n                  }}\n                />\n              </Grid>\n              <Grid\n                item\n                style={{\n                  display: \"flex\",\n                  justifyContent: \"center\",\n                }}\n              >\n                <PhoneInput\n                  country={\"in\"}\n                  value={phone}\n                  onChange={(phone) => setPhone(phone)}\n                  style={{ width: \"auto\" }}\n                />\n              </Grid>\n            </Grid>\n            <Button\n              variant=\"contained\"\n              color=\"primary\"\n              style={{ padding: \"10px 50px\", marginTop: \"30px\" }}\n              onClick={() => handleUpdate()}\n            >\n              Update Details\n            </Button>\n          </Paper>\n        </Grid>\n      </Grid>\n    </>\n  );\n};\n\nexport default Profile;\n"
  },
  {
    "path": "frontend/src/index.css",
    "content": "body {\n  margin: 0;\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n    sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n    monospace;\n}\n"
  },
  {
    "path": "frontend/src/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n  <React.StrictMode>\n    <App />\n  </React.StrictMode>,\n  document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"
  },
  {
    "path": "frontend/src/lib/EmailInput.js",
    "content": "import { TextField } from \"@material-ui/core\";\n\nconst EmailInput = (props) => {\n  const {\n    label,\n    value,\n    onChange,\n    inputErrorHandler,\n    handleInputError,\n    required,\n    className,\n  } = props;\n\n  return (\n    <TextField\n      label={label}\n      variant=\"outlined\"\n      value={value}\n      onChange={onChange}\n      helperText={inputErrorHandler.email.message}\n      onBlur={(event) => {\n        if (event.target.value === \"\") {\n          if (required) {\n            handleInputError(\"email\", true, \"Email is required\");\n          } else {\n            handleInputError(\"email\", false, \"\");\n          }\n        } else {\n          const 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,}))$/;\n          if (re.test(String(event.target.value).toLowerCase())) {\n            handleInputError(\"email\", false, \"\");\n          } else {\n            handleInputError(\"email\", true, \"Incorrect email format\");\n          }\n        }\n      }}\n      error={inputErrorHandler.email.error}\n      className={className}\n    />\n  );\n};\n\nexport default EmailInput;\n"
  },
  {
    "path": "frontend/src/lib/FileUploadInput.js",
    "content": "import { useState, useContext } from \"react\";\nimport { Grid, Button, TextField, LinearProgress } from \"@material-ui/core\";\nimport { CloudUpload } from \"@material-ui/icons\";\nimport Axios from \"axios\";\n\nimport { SetPopupContext } from \"../App\";\n\nconst FileUploadInput = (props) => {\n  const setPopup = useContext(SetPopupContext);\n\n  const { uploadTo, identifier, handleInput } = props;\n\n  const [file, setFile] = useState(\"\");\n  const [uploadPercentage, setUploadPercentage] = useState(0);\n\n  const handleUpload = () => {\n    console.log(file);\n    const data = new FormData();\n    data.append(\"file\", file);\n    Axios.post(uploadTo, data, {\n      headers: {\n        \"Content-Type\": \"multipart/form-data\",\n      },\n      onUploadProgress: (progressEvent) => {\n        setUploadPercentage(\n          parseInt(\n            Math.round((progressEvent.loaded * 100) / progressEvent.total)\n          )\n        );\n      },\n    })\n      .then((response) => {\n        console.log(response.data);\n        handleInput(identifier, response.data.url);\n        setPopup({\n          open: true,\n          severity: \"success\",\n          message: response.data.message,\n        });\n      })\n      .catch((err) => {\n        console.log(err.response);\n        setPopup({\n          open: true,\n          severity: \"error\",\n          message: err.response.statusText,\n          //   message: err.response.data\n          //     ? err.response.data.message\n          //     : err.response.statusText,\n        });\n      });\n  };\n\n  return (\n    <Grid container item xs={12} direction=\"column\" className={props.className}>\n      <Grid container item xs={12} spacing={0}>\n        <Grid item xs={3}>\n          <Button\n            variant=\"contained\"\n            color=\"primary\"\n            component=\"label\"\n            style={{ width: \"100%\", height: \"100%\" }}\n          >\n            {props.icon}\n            <input\n              type=\"file\"\n              style={{ display: \"none\" }}\n              onChange={(event) => {\n                console.log(event.target.files);\n                setUploadPercentage(0);\n                setFile(event.target.files[0]);\n              }}\n              // onChange={onChange}\n              // onChange={\n              //   (e) => {}\n              //   //   setSource({ ...source, place_img: e.target.files[0] })\n              // }\n            />\n          </Button>\n        </Grid>\n        <Grid item xs={6}>\n          <TextField\n            label={props.label}\n            value={file ? file.name || \"\" : \"\"}\n            InputProps={{\n              readOnly: true,\n            }}\n            variant=\"outlined\"\n            style={{ width: \"100%\" }}\n          />\n        </Grid>\n        <Grid item xs={3}>\n          <Button\n            variant=\"contained\"\n            color=\"secondary\"\n            style={{ width: \"100%\", height: \"100%\" }}\n            onClick={() => handleUpload()}\n            disabled={file ? false : true}\n          >\n            <CloudUpload />\n          </Button>\n        </Grid>\n      </Grid>\n      {uploadPercentage !== 0 ? (\n        <Grid item xs={12} style={{ marginTop: \"10px\" }}>\n          <LinearProgress variant=\"determinate\" value={uploadPercentage} />\n        </Grid>\n      ) : null}\n    </Grid>\n  );\n};\n\nexport default FileUploadInput;\n"
  },
  {
    "path": "frontend/src/lib/MessagePopup.js",
    "content": "import { Snackbar, Slide } from \"@material-ui/core\";\nimport { Alert } from \"@material-ui/lab\";\n\nconst MessagePopup = (props) => {\n  const handleClose = (event, reason) => {\n    if (reason === \"clickaway\") {\n      return;\n    }\n    props.setOpen(false);\n  };\n  return (\n    <Snackbar open={props.open} onClose={handleClose} autoHideDuration={2000}>\n      <Alert onClose={handleClose} severity={props.severity}>\n        {props.message}\n      </Alert>\n    </Snackbar>\n  );\n};\n\nexport default MessagePopup;\n"
  },
  {
    "path": "frontend/src/lib/PasswordInput.js",
    "content": "import { useState } from \"react\";\nimport {\n  FormControl,\n  InputLabel,\n  OutlinedInput,\n  InputAdornment,\n  IconButton,\n  FormHelperText,\n} from \"@material-ui/core\";\nimport Visibility from \"@material-ui/icons/Visibility\";\nimport VisibilityOff from \"@material-ui/icons/VisibilityOff\";\n\nconst PasswordInput = (props) => {\n  const [showPassword, setShowPassword] = useState(false);\n\n  const handleShowPassword = () => {\n    setShowPassword(!showPassword);\n  };\n\n  const handleMouseDownPassword = (event) => {\n    event.preventDefault();\n  };\n\n  return (\n    <>\n      <FormControl variant=\"outlined\" error={props.error ? props.error : null}>\n        <InputLabel htmlFor=\"outlined-adornment-password\">\n          {props.label}\n        </InputLabel>\n        <OutlinedInput\n          id=\"outlined-adornment-password\"\n          type={showPassword ? \"text\" : \"password\"}\n          endAdornment={\n            <InputAdornment position=\"end\">\n              <IconButton\n                onClick={handleShowPassword}\n                onMouseDown={handleMouseDownPassword}\n                edge=\"end\"\n              >\n                {showPassword ? <Visibility /> : <VisibilityOff />}\n              </IconButton>\n            </InputAdornment>\n          }\n          value={props.value}\n          onChange={(event) => props.onChange(event)}\n          labelWidth={props.labelWidth ? props.labelWidth : 70}\n          className={props.className}\n          onBlur={props.onBlur ? props.onBlur : null}\n        />\n        {props.helperText ? (\n          <FormHelperText>{props.helperText}</FormHelperText>\n        ) : null}\n      </FormControl>\n    </>\n  );\n};\n\nexport default PasswordInput;\n"
  },
  {
    "path": "frontend/src/lib/apiList.js",
    "content": "export const server = \"http://localhost:4444\";\n\nconst apiList = {\n  login: `${server}/auth/login`,\n  signup: `${server}/auth/signup`,\n  uploadResume: `${server}/upload/resume`,\n  uploadProfileImage: `${server}/upload/profile`,\n  jobs: `${server}/api/jobs`,\n  applications: `${server}/api/applications`,\n  rating: `${server}/api/rating`,\n  user: `${server}/api/user`,\n  applicants: `${server}/api/applicants`,\n};\n\nexport default apiList;\n"
  },
  {
    "path": "frontend/src/lib/isAuth.js",
    "content": "const isAuth = () => {\n  return localStorage.getItem(\"token\");\n};\n\nexport const userType = () => {\n  return localStorage.getItem(\"type\");\n};\n\nexport default isAuth;\n"
  },
  {
    "path": "frontend/src/reportWebVitals.js",
    "content": "const reportWebVitals = onPerfEntry => {\n  if (onPerfEntry && onPerfEntry instanceof Function) {\n    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n      getCLS(onPerfEntry);\n      getFID(onPerfEntry);\n      getFCP(onPerfEntry);\n      getLCP(onPerfEntry);\n      getTTFB(onPerfEntry);\n    });\n  }\n};\n\nexport default reportWebVitals;\n"
  },
  {
    "path": "frontend/src/setupTests.js",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom';\n"
  }
]