├── src
├── Graphql
│ ├── index.js
│ ├── Queries
│ │ ├── index.js
│ │ ├── admin.js
│ │ ├── recruter.js
│ │ ├── AdminViewStudents
│ │ │ └── adminViewStudents.js
│ │ └── recruiter.js
│ └── Mutations
│ │ ├── index.js
│ │ ├── admin.js
│ │ └── recruter.js
├── Utils
│ ├── postgresConnection.js
│ ├── supabase.config.js
│ ├── isLoggedIn.js
│ ├── PrivateOutlet.js
│ └── ApolloClient.js
├── Screens
│ ├── index.jsx
│ ├── error404.jpg
│ ├── Home
│ │ ├── Code_Miners Recruitment Portal for VJTI Proposal (1).pdf
│ │ ├── Home.jsx
│ │ ├── Header.jsx
│ │ ├── header.css
│ │ ├── MainHome.module.css
│ │ ├── MainHome.jsx
│ │ └── About.jsx
│ ├── HR
│ │ ├── PastJobs
│ │ │ ├── Pastjobs.module.css
│ │ │ ├── CardGrid.css
│ │ │ ├── PastJobs.jsx
│ │ │ └── ApplicantListTable
│ │ │ │ └── ApplicantListTable.jsx
│ │ ├── CreateJob
│ │ │ ├── CreateJob.module.css
│ │ │ └── CreateJob.jsx
│ │ ├── Profile
│ │ │ ├── Profile.module.css
│ │ │ └── Profile.jsx
│ │ ├── Job.jsx
│ │ ├── RegisterHr
│ │ │ └── RegisterHR.jsx
│ │ ├── CreateRound.jsx
│ │ ├── ApplicantList.jsx
│ │ └── RoundDetail.jsx
│ ├── Admin
│ │ ├── TpoPolicy
│ │ │ ├── TpoPolicy.module.css
│ │ │ └── TpoPolicy.jsx
│ │ ├── Schedule.jsx
│ │ ├── Profile
│ │ │ ├── Profile.module.css
│ │ │ └── Profile.jsx
│ │ ├── Dashboard
│ │ │ └── Dashboard.jsx
│ │ ├── RegisterAdmin
│ │ │ └── RegisterAdmin.jsx
│ │ └── ViewStudents
│ │ │ └── ViewStudents.jsx
│ ├── Logout.jsx
│ ├── Error.jsx
│ └── Login
│ │ └── Login.jsx
├── Components
│ ├── Header.jsx
│ ├── Loader.jsx
│ ├── dashboard
│ │ ├── DashboardHeading.jsx
│ │ ├── DashboardTable.jsx
│ │ └── DashboardCard.jsx
│ ├── hrSidebar
│ │ ├── hrSidebar.js
│ │ ├── Sidebar.jsx
│ │ └── Sidebar.module.css
│ ├── AdminViewStudents
│ │ ├── CriteriaDropdown.jsx
│ │ └── StudentsTable.jsx
│ ├── adminSidebar
│ │ ├── ASidebar.jsx
│ │ ├── Sidebar.module.css
│ │ └── adminSidebar.js
│ └── Rounds
│ │ └── RoundsHeaderCard.jsx
├── constants
│ ├── interviewRoundConstants.js
│ └── userConstants.js
├── reportWebVitals.js
├── index.css
├── App.css
├── index.js
├── reducers
│ ├── interviewRoundReducer.js
│ └── userReducer.js
├── store.js
├── actions
│ ├── interviewRoundActions.js
│ └── userActions.js
└── App.js
├── public
├── _redirects
├── dog.jpg
├── robots.txt
├── sahil.jpg
├── dhruvi.jpg
├── favicon.ico
├── pranit.jpg
├── manifest.json
└── index.html
├── tailwind.config.js
├── .gitignore
├── README.md
└── package.json
/src/Graphql/index.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Utils/postgresConnection.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/src/Screens/index.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
--------------------------------------------------------------------------------
/src/Graphql/Queries/index.js:
--------------------------------------------------------------------------------
1 | import { gql } from "@apollo/client";
--------------------------------------------------------------------------------
/src/Graphql/Mutations/index.js:
--------------------------------------------------------------------------------
1 | import { gql } from "@apollo/client";
2 |
--------------------------------------------------------------------------------
/public/dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/public/dog.jpg
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/sahil.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/public/sahil.jpg
--------------------------------------------------------------------------------
/public/dhruvi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/public/dhruvi.jpg
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/pranit.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/public/pranit.jpg
--------------------------------------------------------------------------------
/src/Screens/error404.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/src/Screens/error404.jpg
--------------------------------------------------------------------------------
/src/Components/Header.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Header = () => {
4 | return <>Header>;
5 | };
6 |
7 | export default Header;
8 |
--------------------------------------------------------------------------------
/src/Screens/Home/Code_Miners Recruitment Portal for VJTI Proposal (1).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PranitRohokale/TPO-Code_miners/HEAD/src/Screens/Home/Code_Miners Recruitment Portal for VJTI Proposal (1).pdf
--------------------------------------------------------------------------------
/src/Screens/HR/PastJobs/Pastjobs.module.css:
--------------------------------------------------------------------------------
1 | .mainCard{
2 | background-color: red;
3 | }
4 |
5 | .btn, .btn-primary {
6 | position: absolute;
7 | bottom: 5px;
8 | color: #263238;
9 | overflow: auto;
10 | }
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/**/*.{js,jsx,ts,tsx}",
5 | ],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
--------------------------------------------------------------------------------
/src/Utils/supabase.config.js:
--------------------------------------------------------------------------------
1 | import { createClient } from '@supabase/supabase-js'
2 |
3 | const supabaseUrl = process.env.REACT_APP_SUPABASE_URL
4 | const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY
5 |
6 | export const supabase = createClient(supabaseUrl, supabaseAnonKey)
--------------------------------------------------------------------------------
/src/Components/Loader.jsx:
--------------------------------------------------------------------------------
1 | import { CircularProgress } from "@mui/material";
2 |
3 | const Loader = ({ color = "primary" }) => {
4 | return (
5 | <>
6 |
7 | >
8 | );
9 | };
10 |
11 | export default Loader;
12 |
--------------------------------------------------------------------------------
/src/Graphql/Queries/admin.js:
--------------------------------------------------------------------------------
1 | import { gql } from "@apollo/client";
2 |
3 | const GET_ALL_USERS_QUERY = gql`
4 | query getAllUsers {
5 | auth_users {
6 | id
7 | role
8 | raw_user_meta_data
9 | }
10 | }
11 | `;
12 |
13 | export {
14 | GET_ALL_USERS_QUERY
15 | }
--------------------------------------------------------------------------------
/src/Screens/HR/CreateJob/CreateJob.module.css:
--------------------------------------------------------------------------------
1 | .hospitals_wrapper {
2 | display: flex;
3 | flex-direction: row;
4 | width: 100%;
5 | height: 100vh;
6 | }
7 |
8 | .main_wrapper {
9 | display: flex;
10 | flex-direction: column;
11 | width: calc(100% - 240px);
12 | overflow: hidden;
13 | overflow-y: scroll;
14 | background-color: #f9fbff;
15 | }
--------------------------------------------------------------------------------
/src/Screens/Admin/TpoPolicy/TpoPolicy.module.css:
--------------------------------------------------------------------------------
1 | .hospitals_wrapper {
2 | display: flex;
3 | flex-direction: row;
4 | width: 100%;
5 | height: 100vh;
6 | }
7 |
8 | .main_wrapper {
9 | display: flex;
10 | flex-direction: column;
11 | width: calc(100% - 240px);
12 | overflow: hidden;
13 | overflow-y: scroll;
14 | background-color: #f9fbff;
15 | }
--------------------------------------------------------------------------------
/src/constants/interviewRoundConstants.js:
--------------------------------------------------------------------------------
1 | export const INTERVIEW_ROUND_ADD = 'INTERVIEW_ROUND_ADD'
2 | export const INTERVIEW_ROUND_ALL = 'INTERVIEW_ROUND_ALL'
3 | export const INTERVIEW_ROUND_REQUEST = 'INTERVIEW_ROUND_REQUEST'
4 | export const INTERVIEW_ROUND_RESET = 'INTERVIEW_ROUND_RESET'
5 | export const INTERVIEW_ROUND_FAILD = 'INTERVIEW_ROUND_FAILD'
6 |
7 |
--------------------------------------------------------------------------------
/src/Graphql/Queries/recruter.js:
--------------------------------------------------------------------------------
1 | import gql from "graphql-tag"
2 |
3 |
4 | const GET_RECRUTER_INFO = gql`
5 | query getRecruterInfo($_eq: uuid = "") {
6 | Recruiters(where: {id: {_eq: $_eq}}) {
7 | id
8 | email
9 | mobileNo
10 | companyName
11 | name
12 | created_at
13 | }
14 | }
15 |
16 | `
17 |
18 | export {
19 | GET_RECRUTER_INFO
20 | }
21 |
--------------------------------------------------------------------------------
/src/Components/dashboard/DashboardHeading.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import {Typography } from "@mui/material";
3 |
4 | const DashboardHeading=({text})=>(
5 |
12 | {text}
13 |
14 | )
15 |
16 | export default DashboardHeading;
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | body {
6 | margin: 0;
7 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
8 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
9 | sans-serif;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
14 | code {
15 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
16 | monospace;
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 |
27 | ./package-lock.json
28 | ./.env
29 | # Local Netlify folder
30 | .netlify
31 |
--------------------------------------------------------------------------------
/src/Screens/Logout.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import { useDispatch, useSelector } from "react-redux";
3 | import { logout } from "../actions/userActions";
4 |
5 | const Logout = () => {
6 | const dispatch = useDispatch();
7 | const [result, setResult] = useState(" Nothing");
8 |
9 | useEffect(() => {
10 | dispatch(logout());
11 | setResult(true);
12 | }, []);
13 |
14 | return (
15 | <>
16 |
{result}
17 | >
18 | );
19 | };
20 |
21 | export default Logout;
22 |
--------------------------------------------------------------------------------
/src/Screens/Home/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Sidebar from '../../Components/hrSidebar/Sidebar'
3 | import ASidebar from '../../Components/adminSidebar/ASidebar'
4 |
5 | const Home = () => {
6 | return (
7 |
8 | {/*
9 |
*/}
10 |
11 |
12 |
Welcome home!
13 |
14 |
15 |
16 | )
17 | }
18 |
19 | export default Home
--------------------------------------------------------------------------------
/src/Utils/isLoggedIn.js:
--------------------------------------------------------------------------------
1 | import { supabase } from "./supabase.config";
2 |
3 |
4 | export const isLoggedIn = async () => {
5 | try {
6 | const { data, error } = await supabase.auth.getSession()
7 |
8 | if (error)
9 | return { error: true, isAuth: false }
10 |
11 | const userId = data?.session?.user?.id
12 | let userRole = data?.session?.user?.user_metadata?.role?.toLowerCase();
13 |
14 | return { userId, userRole, isAuth: true }
15 | } catch (error) {
16 | return { error: true, isAuth: false }
17 | }
18 | }
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/constants/userConstants.js:
--------------------------------------------------------------------------------
1 | export const ADMIN_LOGIN_REQUEST = 'ADMIN_LOGIN_REQUEST'
2 | export const ADMIN_LOGIN_SUCCESS = 'ADMIN_LOGIN_SUCCESS'
3 | export const ADMIN_LOGIN_FAIL = 'ADMIN_LOGIN_FAIL'
4 | export const ADMIN_LOGOUT = 'ADMIN_LOGOUT'
5 |
6 | export const ADMIN_REGISTER_REQUEST = 'ADMIN_REGISTER_REQUEST'
7 | export const ADMIN_REGISTER_SUCCESS = 'ADMIN_REGISTER_SUCCESS'
8 | export const ADMIN_REGISTER_FAIL = 'ADMIN_REGISTER_FAIL'
9 |
10 | export const ADMIN_DETAILS_REQUEST = 'ADMIN_DETAILS_REQUEST'
11 | export const ADMIN_DETAILS_SUCCESS = 'ADMIN_DETAILS_SUCCESS'
12 | export const ADMIN_DETAILS_FAIL = 'ADMIN_DETAILS_FAIL'
13 | export const ADMIN_DETAILS_RESET = 'ADMIN_DETAILS_RESET'
--------------------------------------------------------------------------------
/src/Screens/HR/PastJobs/CardGrid.css:
--------------------------------------------------------------------------------
1 | .card-group {
2 | justify-content: center;
3 | }
4 |
5 | .card-grid, .card {
6 | padding: 5px 5px !important;
7 | height: auto !important;
8 | justify-content: center;
9 | margin: 1rem;
10 | }
11 |
12 | .card-body {
13 | background-color: #F6F5F5;
14 | margin: 0;
15 | }
16 |
17 | .card-img,
18 | .card-img-top,
19 | .card-img-bottom {
20 | height: 10rem;
21 | width: auto;
22 | align-content: flex-start;
23 | }
24 |
25 | .card-text {
26 | height: fit-content;
27 | margin-bottom: 2rem;
28 | }
29 |
30 | .btn, .btn-primary {
31 | position: absolute;
32 | bottom: 5px;
33 | color: #263238;
34 | overflow: auto;
35 | }
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 | import { Provider } from 'react-redux'
7 | import store from './store';
8 | import { ApolloProvider } from '@apollo/client';
9 | import client from "./Utils/ApolloClient"
10 | import { getUserDetails } from './actions/userActions';
11 |
12 | const root = ReactDOM.createRoot(document.getElementById('root'));
13 |
14 | store.dispatch(getUserDetails())
15 |
16 | root.render(
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | );
25 |
26 |
27 | reportWebVitals();
28 |
--------------------------------------------------------------------------------
/src/Components/hrSidebar/hrSidebar.js:
--------------------------------------------------------------------------------
1 | import Person2Icon from "@mui/icons-material/Person2";
2 | import AddBoxIcon from '@mui/icons-material/AddBox';
3 | import HistoryIcon from '@mui/icons-material/History';
4 | import LogoutIcon from '@mui/icons-material/Logout';
5 | import styles from "./Sidebar.module.css";
6 |
7 | export const hrSidebar = [
8 | {
9 | name: "Create Job",
10 | url: "/hr/createjob",
11 | icon: ,
12 | },
13 |
14 | {
15 | name: "Jobs Created",
16 | url: "/hr/createdjobs",
17 | icon: ,
18 | },
19 | {
20 | name: "Profile",
21 | url: "/hr/profile",
22 | icon: ,
23 | },
24 | {
25 | name: "Logout",
26 | url: "/logout",
27 | icon: ,
28 | },
29 | ];
30 |
--------------------------------------------------------------------------------
/src/Utils/PrivateOutlet.js:
--------------------------------------------------------------------------------
1 | import { Navigate, Outlet } from "react-router-dom";
2 | import { useSelector } from "react-redux";
3 | import Error from "../Screens/Error";
4 |
5 |
6 | const PrivateRoute = ({ role = "" }) => {
7 | const userDetails = useSelector(state => state.userDetails)
8 |
9 | const { userInfo, loading, error } = userDetails
10 | let userId = userInfo?.id
11 | let userRole = userInfo?.user_metadata?.role?.toLowerCase()
12 |
13 | // console.log(id, user_metadata)
14 |
15 | // console.log("HEEEEY", userId, userRole);
16 |
17 | if (error)
18 | return ( )
19 | else if (userRole === role.toLowerCase() && userId)
20 | return
21 |
22 |
23 | return ;
24 | }
25 |
26 |
27 | export default PrivateRoute;
28 |
--------------------------------------------------------------------------------
/src/Utils/ApolloClient.js:
--------------------------------------------------------------------------------
1 | import { ApolloClient, InMemoryCache ,createHttpLink} from '@apollo/client';
2 | import { setContext } from '@apollo/client/link/context';
3 |
4 | const httpLink = createHttpLink({
5 | uri: process.env.REACT_APP_GRAPHQL_URL,
6 | });
7 |
8 | const authLink = setContext((_, { headers }) => {
9 | // get the authentication token from local storage if it exists
10 | const token = localStorage.getItem('token');
11 | // return the headers to the context so httpLink can read them
12 | return {
13 | headers: {
14 | ...headers,
15 | authorization: token ? `Bearer ${token}` : "",
16 | "x-hasura-admin-secret" : process.env.REACT_APP_GRAPHQL_SECRET,
17 | }
18 | }
19 | });
20 |
21 | const client = new ApolloClient({
22 | link: authLink.concat(httpLink),
23 | cache: new InMemoryCache()
24 | });
25 |
26 |
27 | export default client
--------------------------------------------------------------------------------
/src/Graphql/Queries/AdminViewStudents/adminViewStudents.js:
--------------------------------------------------------------------------------
1 | import { gql } from "@apollo/client";
2 |
3 | const GET_ALL_STUDENTS = gql`
4 | query getAllStudents($where: Students_bool_exp = {}) {
5 | Students(where: $where, order_by: {clgId: asc}) {
6 | CPI
7 | SPI1
8 | SPI2
9 | SPI3
10 | SPI4
11 | SPI5
12 | SPI6
13 | SPI7
14 | SPI8
15 | age
16 | branch
17 | clgEmail
18 | clgId
19 | column_10th
20 | column_12th
21 | created_at
22 | dob
23 | firstName
24 | gender
25 | gradYear
26 | id
27 | isCr
28 | isDreamPlaced
29 | isNormalPlaced
30 | isSuperPlaced
31 | lastName
32 | middleName
33 | mobileNumber
34 | programme
35 | resumeLink
36 | }
37 | }
38 |
39 | `;
40 |
41 | export {
42 | GET_ALL_STUDENTS
43 | }
--------------------------------------------------------------------------------
/src/Screens/Admin/Schedule.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useNavigate } from "react-router-dom";
3 |
4 | const Schedule = () => {
5 | const navigate = useNavigate();
6 |
7 | return (
8 |
9 |
10 | {
12 | e.preventDefault();
13 | navigate(
14 | `/admin`
15 | );
16 | }}>
17 | Home
18 |
19 |
20 |
21 | )
22 | }
23 |
24 | export default Schedule
--------------------------------------------------------------------------------
/src/Graphql/Mutations/admin.js:
--------------------------------------------------------------------------------
1 | import { gql } from '@apollo/client';
2 |
3 | const CREATE_NEW_ADMIN_MUTATION = gql`
4 | mutation createNewTpo($objects: [TPO_Heads_insert_input!]!) {
5 | insert_TPO_Heads(objects: $objects) {
6 | affected_rows
7 | returning {
8 | id
9 | firstName
10 | clgEmail
11 | }
12 | }
13 | }
14 | `;
15 |
16 | const GET_ADMIN_INFO_QUERY = gql`
17 | query getAdminInfo($id: uuid = "") {
18 | TPO_Heads_by_pk(id: $id) {
19 | firstName
20 | middleName
21 | lastName
22 | id
23 | gender
24 | dob
25 | clgEmail
26 | inserted_at
27 | }
28 | }
29 | `;
30 |
31 | const UPDATE_STUDENT_FOR_CR_MUTATION = gql`
32 | mutation updateStudent($id: uuid = "", $isCr: Boolean = false) {
33 | update_Students_by_pk(pk_columns: {id: $id}, _set: {isCr: $isCr}) {
34 | id
35 | isCr
36 | }
37 | }
38 | `;
39 |
40 | export {
41 | CREATE_NEW_ADMIN_MUTATION,
42 | GET_ADMIN_INFO_QUERY,
43 | UPDATE_STUDENT_FOR_CR_MUTATION
44 | }
--------------------------------------------------------------------------------
/src/reducers/interviewRoundReducer.js:
--------------------------------------------------------------------------------
1 | import { INTERVIEW_ROUND_ADD, INTERVIEW_ROUND_ALL, INTERVIEW_ROUND_REQUEST, INTERVIEW_ROUND_RESET, INTERVIEW_ROUND_FAILD } from "../constants/interviewRoundConstants"
2 |
3 |
4 |
5 | export const interviewRoundReducer = (state = { rounds: [] }, action) => {
6 | switch (action.type) {
7 | case INTERVIEW_ROUND_REQUEST:
8 | return { ...state, loading: true, error: false }
9 | case INTERVIEW_ROUND_FAILD:
10 | return { ...state, loading: false, error: action.payload || true }
11 | case INTERVIEW_ROUND_RESET:
12 | return { rounds: [] }
13 | case INTERVIEW_ROUND_ADD:
14 | let existingRounds = state.rounds
15 | let newRound = action.payload
16 | return { rounds: [...existingRounds, newRound], loading: false, error: false }
17 | case INTERVIEW_ROUND_ALL:
18 | return { rounds: action.payload, loading: false, error: false }
19 | default:
20 | return state
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Components/AdminViewStudents/CriteriaDropdown.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | MenuItem,
3 | FormControl,
4 | InputLabel,
5 | Select,
6 | } from "@mui/material";
7 |
8 | const CriteriaDropdown = ({
9 | inputLabel,
10 | label,
11 | defaultVal,
12 | defaultValName,
13 | chosen,
14 | handleChange,
15 | available,
16 | }) => {
17 | return (
18 |
19 | {inputLabel}
20 |
27 | {defaultValName}
28 | {available.map((row, index) => (
29 |
30 | {row}
31 |
32 | ))}
33 |
34 |
35 | );
36 | };
37 | export default CriteriaDropdown;
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Placement Portal
3 |
4 |
5 |
6 | Our Recruitment portal is designed to keep track of all the records of the students, companies , TPO and provide them a smart platform to interact with each other. Our goal is to reduce the reliance on manual processes, streamline the processes of the Recruitment to minimize the amount of time and effort required .
7 |
8 |
9 |
10 |
11 |
12 | ## 🔗 Links
13 | - [Student Mobile Interface](https://github.com/dhruvi29/TPO-VJTI-Mobile)
14 | - [Confluence Doc For Graphql](https://drive.google.com/file/d/1QDvpZIceINM61qgYCZZsQclf50i38Txz/view?usp=sharing)
15 |
16 |
17 |
18 | ## Our Three Roles
19 | - Admin
20 | - ● Create Company Schedule
21 |
22 | - ● Invite Companies
23 |
24 | - ● Manage CRs
25 |
26 | - Recruiter
27 | - ● Create New Job Postings
28 |
29 | - ● Access Created Jobs
30 |
31 | - ● Post Selection Roundwise
32 |
33 | - Student
34 | - ● Apply For Eligible Jobs
35 |
36 | - ● View Daily Placement Updates
37 |
38 | - ● Generate Resumes
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/Components/hrSidebar/Sidebar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { hrSidebar } from "./hrSidebar";
4 | import styles from "./Sidebar.module.css";
5 |
6 | const Sidebar = ({ value }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
32 |
33 | );
34 | };
35 |
36 | export default Sidebar;
37 |
--------------------------------------------------------------------------------
/src/Components/adminSidebar/ASidebar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { adminSidebar } from "./adminSidebar";
4 | import styles from "./Sidebar.module.css";
5 |
6 | const ASidebar = ({ value }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
32 |
33 | );
34 | };
35 |
36 | export default ASidebar;
37 |
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, combineReducers, applyMiddleware } from 'redux'
2 | import thunk from 'redux-thunk'
3 | import { composeWithDevTools } from 'redux-devtools-extension'
4 | import { supabase } from './Utils/supabase.config'
5 | import { userRegisterReducer, userLoginReducer, userDetailsReducer } from './reducers/userReducer'
6 | import { interviewRoundReducer } from './reducers/interviewRoundReducer'
7 |
8 | const reducer = combineReducers({
9 | userRegister: userRegisterReducer,
10 | userLogin: userLoginReducer,
11 | userDetails: userDetailsReducer,
12 | interviewRounds: interviewRoundReducer
13 | })
14 |
15 | const userInfoFromSession = () => {
16 |
17 | try {
18 | return supabase.auth.getSession()
19 | .then(res => res)
20 | .catch(e => undefined)
21 | // return data;
22 | } catch (error) {
23 | console.log("ERROR AT STORE ", error);
24 | }
25 | return undefined;
26 | }
27 | const _userInfoFromSession = userInfoFromSession()
28 |
29 | const initialState = {
30 | userLogin: { userInfo: _userInfoFromSession },
31 | }
32 |
33 | const middleware = [thunk]
34 |
35 | const store = createStore(
36 | reducer,
37 | initialState,
38 | composeWithDevTools(applyMiddleware(...middleware))
39 | )
40 |
41 | export default store
--------------------------------------------------------------------------------
/src/Components/adminSidebar/Sidebar.module.css:
--------------------------------------------------------------------------------
1 | .sidebar_wrapper {
2 | display: flex;
3 | width: 240px;
4 | min-height: 100vh;
5 | flex-direction: column;
6 | padding: 20px 10px;
7 | /* background-color: #003459; */
8 | overflow: hidden;
9 | /* background-color: #3c4fff; */
10 | /* background-color: #219ebc; */
11 | /* background-color: #ea5858; */
12 | background-color:#EB455F;
13 | /* background-color:#FD8A8A; */
14 | overflow: hidden;
15 | }
16 |
17 | .logoDiv {
18 | height: 50px;
19 | padding: 0 20px;
20 | padding-left: 25px;
21 | font-size: 25px;
22 | font-weight: 600;
23 | color: rgb(0, 0, 0);
24 | }
25 |
26 | .sidebarList {
27 | padding: 0 8px;
28 | list-style-type: none;
29 | }
30 |
31 | .sidebarList li {
32 | text-decoration: none;
33 | margin: 10px 0;
34 | }
35 |
36 | .sidebarList li div {
37 | text-decoration: none;
38 | font-size: 17px;
39 | display: flex;
40 | flex-direction: row;
41 | border-radius: 5px;
42 | color: rgb(0, 0, 0);
43 | padding: 10px 20px;
44 | }
45 |
46 | .sidebarList li div:hover,
47 | .active {
48 | background-color: #f8a28a;
49 | /* background-color: #ea5858; */
50 | /* background-color:#EB455F; */
51 | background-color:#FD8A8A;
52 | cursor: pointer;
53 | }
54 |
55 | .sidebarList li div .listIcon {
56 | margin-right: 10px;
57 | color: white;
58 | }
59 |
60 | .sidebarList li div a {
61 | color: rgb(255, 255, 255);
62 | }
--------------------------------------------------------------------------------
/src/Components/hrSidebar/Sidebar.module.css:
--------------------------------------------------------------------------------
1 | .sidebar_wrapper {
2 | display: flex;
3 | width: 240px;
4 | height: 100vh;
5 | flex-direction: column;
6 | padding: 20px 10px;
7 | background-color: #013d68;
8 | overflow: hidden;
9 | /* background-color: #fbd951; */
10 | /* background-color: #3c4fff; */
11 | /* background-color: #22a6c7; */
12 | /* background-color: #7a87fc; */
13 | /* background-color: #0087ca; */
14 | /* background-color: #003459; */
15 | /* background-color: #3c4fff; */
16 | /* background-color: #219ebc; */
17 | /* background-color: #ee8282; */
18 | }
19 |
20 | .logoDiv {
21 | height: 50px;
22 | padding: 0 20px;
23 | padding-left: 25px;
24 | font-size: 25px;
25 | font-weight: 600;
26 | color: rgb(0, 0, 0);
27 | }
28 |
29 | .sidebarList {
30 | padding: 0 8px;
31 | list-style-type: none;
32 | }
33 |
34 | .sidebarList li {
35 | text-decoration: none;
36 | margin: 10px 0;
37 | }
38 |
39 | .sidebarList li div {
40 | text-decoration: none;
41 | font-size: 17px;
42 | display: flex;
43 | flex-direction: row;
44 | border-radius: 5px;
45 | color: rgb(0, 0, 0);
46 | padding: 10px 20px;
47 | }
48 |
49 | .sidebarList li div:hover,
50 | .active {
51 | /* background-color: #efe585; */
52 | background-color: #007ea7;
53 |
54 | cursor: pointer;
55 | }
56 |
57 | .sidebarList li div .listIcon {
58 | margin-right: 10px;
59 | /* color: white; */
60 | color: rgb(255, 255, 255);
61 | }
62 |
63 | .sidebarList li div a {
64 | color: rgb(255, 255, 255);
65 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "centenary_hack",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@apollo/client": "^3.7.3",
7 | "@emotion/react": "^11.10.5",
8 | "@emotion/styled": "^11.10.5",
9 | "@mui/icons-material": "^5.11.0",
10 | "@mui/material": "^5.11.4",
11 | "@supabase/supabase-js": "^2.4.0",
12 | "@testing-library/jest-dom": "^5.16.5",
13 | "@testing-library/react": "^13.4.0",
14 | "@testing-library/user-event": "^13.5.0",
15 | "graphql": "^16.6.0",
16 | "moment": "^2.29.4",
17 | "react": "^18.2.0",
18 | "react-bootstrap": "^2.7.0",
19 | "react-dom": "^18.2.0",
20 | "react-redux": "^8.0.5",
21 | "react-router-dom": "^6.6.2",
22 | "react-scripts": "5.0.1",
23 | "redux": "^4.2.0",
24 | "redux-devtools-extension": "^2.13.9",
25 | "redux-thunk": "^2.4.2",
26 | "web-vitals": "^2.1.4"
27 | },
28 | "scripts": {
29 | "start": "react-scripts start",
30 | "build": "react-scripts build",
31 | "test": "react-scripts test",
32 | "eject": "react-scripts eject"
33 | },
34 | "eslintConfig": {
35 | "extends": [
36 | "react-app",
37 | "react-app/jest"
38 | ]
39 | },
40 | "browserslist": {
41 | "production": [
42 | ">0.2%",
43 | "not dead",
44 | "not op_mini all"
45 | ],
46 | "development": [
47 | "last 1 chrome version",
48 | "last 1 firefox version",
49 | "last 1 safari version"
50 | ]
51 | },
52 | "devDependencies": {
53 | "tailwindcss": "^3.2.4"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Components/dashboard/DashboardTable.jsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Table from '@mui/material/Table';
3 | import TableBody from '@mui/material/TableBody';
4 | import TableCell from '@mui/material/TableCell';
5 | import TableContainer from '@mui/material/TableContainer';
6 | import TableHead from '@mui/material/TableHead';
7 | import TableRow from '@mui/material/TableRow';
8 | import Paper from '@mui/material/Paper';
9 |
10 | const DashboardTable = ({rows})=> {
11 | return (
12 |
13 |
14 |
15 |
16 | Company Name
17 | CTC
18 | Students recruited
19 |
20 |
21 |
22 | {rows.map((row) => (
23 |
27 |
28 | {row.name}
29 |
30 | {row.ctc}
31 | {row.students}
32 |
33 | ))}
34 |
35 |
36 |
37 | );
38 | }
39 | export default DashboardTable;
--------------------------------------------------------------------------------
/src/reducers/userReducer.js:
--------------------------------------------------------------------------------
1 | import { ADMIN_REGISTER_FAIL, ADMIN_REGISTER_REQUEST, ADMIN_REGISTER_SUCCESS, ADMIN_LOGOUT, ADMIN_LOGIN_REQUEST, ADMIN_LOGIN_FAIL, ADMIN_LOGIN_SUCCESS ,ADMIN_DETAILS_FAIL,ADMIN_DETAILS_REQUEST,ADMIN_DETAILS_RESET,ADMIN_DETAILS_SUCCESS } from "../constants/userConstants"
2 |
3 | export const userRegisterReducer = (state = {}, action) => {
4 | switch (action.type) {
5 | case ADMIN_REGISTER_REQUEST:
6 | return { loading: true }
7 | case ADMIN_REGISTER_SUCCESS:
8 | return { loading: false, userInfo: action.payload }
9 | case ADMIN_REGISTER_FAIL:
10 | return { loading: false, error: action.payload }
11 | case ADMIN_LOGOUT:
12 | return {}
13 | default:
14 | return state
15 | }
16 | }
17 |
18 | export const userLoginReducer = (state = {}, action) => {
19 | switch (action.type) {
20 | case ADMIN_LOGIN_REQUEST:
21 | return { loading: true }
22 | case ADMIN_LOGIN_SUCCESS:
23 | return { loading: false, userInfo: action.payload }
24 | case ADMIN_LOGIN_FAIL:
25 | return { loading: false, error: action.payload }
26 | case ADMIN_LOGOUT:
27 | return {}
28 | default:
29 | return state
30 | }
31 | }
32 |
33 | export const userDetailsReducer = (state = { }, action) => {
34 | switch (action.type) {
35 | case ADMIN_DETAILS_REQUEST:
36 | return { ...state, loading: true }
37 | case ADMIN_DETAILS_SUCCESS:
38 | return { loading: false, userInfo: action.payload }
39 | case ADMIN_DETAILS_FAIL:
40 | return { loading: false, error: action.payload }
41 | case ADMIN_DETAILS_RESET:
42 | return { userInfo: {} }
43 | default:
44 | return state
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Components/Rounds/RoundsHeaderCard.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Card, CardActions, CardContent, Typography } from "@mui/material";
3 |
4 | const RoundHeaderCard = ({desc, value}) => {//, color_val
5 | return (
6 |
24 |
35 |
42 | {desc}
43 |
44 |
51 | {value}
52 |
53 |
54 |
61 |
62 | );
63 | };
64 |
65 | export default RoundHeaderCard;
66 |
--------------------------------------------------------------------------------
/src/Components/AdminViewStudents/StudentsTable.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import {
3 | Table,
4 | TableBody,
5 | TableCell,
6 | TableContainer,
7 | TableHead,
8 | TableRow,
9 | Paper,
10 | Checkbox,
11 | } from "@mui/material";
12 |
13 | const StudentsTable = ({ rows }) => {
14 | return (
15 |
16 |
17 |
18 |
19 | Student Name
20 | Branch
21 | ID
22 | Grad Year
23 | Gender
24 | Is CR
25 |
26 |
27 |
28 | {rows.map((row) => (
29 |
33 |
34 | {row.firstName+" "+row.lastName}
35 |
36 | {row.branch}
37 | {row.clgId}
38 | {row.gradYear}
39 | {row.gender}
40 |
41 |
42 | ))}
43 |
44 |
45 |
46 | );
47 | };
48 | export default StudentsTable;
49 |
--------------------------------------------------------------------------------
/src/Components/adminSidebar/adminSidebar.js:
--------------------------------------------------------------------------------
1 | import DashboardIcon from "@mui/icons-material/Dashboard";
2 | import BiotechIcon from "@mui/icons-material/Biotech";
3 | import PolicyIcon from '@mui/icons-material/Policy';
4 | import EventNoteIcon from '@mui/icons-material/EventNote';
5 | import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
6 | import ForwardToInboxIcon from '@mui/icons-material/ForwardToInbox';
7 | import LogoutIcon from '@mui/icons-material/Logout';
8 | import styles from "./Sidebar.module.css";
9 |
10 | export const adminSidebar = [
11 | {
12 | name: "Dashboard",
13 | url: "/admin",
14 | icon: ,
15 | },
16 | {
17 | name: "Tpo Policy",
18 | url: "/admin/tpopolicy",
19 | icon: ,
20 |
21 | },
22 | {
23 | name: "Student list",
24 | url: "/admin/studentlist",
25 | icon: ,
26 | },
27 | {
28 | name: "Schedule",
29 | url: "/admin/schedule",
30 | icon: ,
31 | },
32 | {
33 | name: "Send Invitations",
34 | url: "/admin/sendinvite",
35 | icon: ,
36 | },
37 | {
38 | name: "Logout",
39 | url: "/logout",
40 | icon: ,
41 | },
42 | // {
43 | // name: "Profile",
44 | // url: "/admin/profile",
45 | // // icon: ,
46 | // },
47 | // {
48 | // name: "Generate analytics",
49 | // url: "/admin/applicants",
50 | // // icon: ,
51 | // },
52 | // {
53 | // name: "Block Students",
54 | // url: "/admin/blockstudents",
55 | // // icon: ,
56 | // },
57 |
58 |
59 | ];
60 |
--------------------------------------------------------------------------------
/src/Components/dashboard/DashboardCard.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Card, CardActions, CardContent, Typography } from "@mui/material";
3 |
4 | const DashboardCard = ({desc, value, color_val}) => {
5 | return (
6 |
25 |
36 | {console.log(color_val)}
37 |
44 | {value}
45 |
46 |
53 | {desc}
54 |
55 |
56 |
63 |
64 | );
65 | };
66 |
67 | export default DashboardCard;
68 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | TPO VJTI
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/actions/interviewRoundActions.js:
--------------------------------------------------------------------------------
1 | import { INTERVIEW_ROUND_ADD, INTERVIEW_ROUND_ALL, INTERVIEW_ROUND_FAILD, INTERVIEW_ROUND_RESET, INTERVIEW_ROUND_REQUEST } from "../constants/interviewRoundConstants";
2 | import { supabase } from "../Utils/supabase.config"
3 |
4 |
5 | export const addNewRound = (newRoundDetail) => async (dispatch) => {
6 | dispatch({
7 | type: INTERVIEW_ROUND_REQUEST,
8 | })
9 |
10 | const { data, error } = await supabase
11 | .from('Rounds')
12 | .insert(newRoundDetail)
13 | .select()
14 |
15 | if (error)
16 | dispatch({
17 | type: INTERVIEW_ROUND_FAILD,
18 | payload: "something went wrong!!"
19 | })
20 | else
21 | dispatch({
22 | type: INTERVIEW_ROUND_ADD,
23 | payload: data?.[0] ?? [],
24 | })
25 | }
26 |
27 | export const getAllRoundsDetails = (jobId) => async (dispatch) => {
28 | try {
29 | dispatch({
30 | type: INTERVIEW_ROUND_REQUEST,
31 | })
32 |
33 |
34 | const { data, error } = await supabase
35 | .from('Rounds')
36 | .select()
37 | .eq('jobId', jobId)
38 | .order('inserted_at', { ascending: true })
39 |
40 | // console.log("getAllRoundsDetails ", data);
41 |
42 | if (error)
43 | dispatch({
44 | type: INTERVIEW_ROUND_FAILD,
45 | payload: "something went wrong!!"
46 | })
47 | else
48 | dispatch({
49 | type: INTERVIEW_ROUND_ALL,
50 | payload: data ?? [],
51 | })
52 | } catch (error) {
53 | const message =
54 | error.response && error.response.data.message
55 | ? error.response.data.message
56 | : error
57 |
58 | dispatch({
59 | type: INTERVIEW_ROUND_FAILD,
60 | payload: message
61 | })
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Screens/Error.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Link } from 'react-router-dom'
3 | import logo from './error404.jpg'
4 | const Error = () => {
5 | return (
6 | <>
7 |
8 |
9 |
10 |
11 |
12 |
15 | 404
16 |
17 |
18 | Oops! That page can’t be found
19 |
20 |
21 | The page you are looking for it maybe deleted
22 |
23 |
27 | Go To Home
28 |
29 |
30 |
31 |
32 |
33 |
51 |
52 |
53 | >
54 |
55 | )
56 | }
57 |
58 | export default Error
--------------------------------------------------------------------------------
/src/Screens/HR/Profile/Profile.module.css:
--------------------------------------------------------------------------------
1 | .hospitals_wrapper {
2 | display: flex;
3 | flex-direction: row;
4 | width: 100%;
5 | height: 100vh;
6 | }
7 |
8 | .main_wrapper {
9 | display: flex;
10 | flex-direction: column;
11 | width: calc(100% - 240px);
12 | overflow: hidden;
13 | overflow-y: scroll;
14 | background-color: #f9fbff;
15 | }
16 |
17 | .navBar {
18 | padding: 15px 50px;
19 | display: flex;
20 | flex-direction: row;
21 | width: 100%;
22 | align-items: center;
23 | justify-content: space-between;
24 | background-color: rgba(182, 232, 255, 0.933);
25 | }
26 |
27 | .user {
28 | font-size: 20px;
29 | font-weight: 500;
30 | }
31 |
32 | .connectButton {
33 | padding: 6px 30px;
34 | color: white;
35 | background-color: #44b4d9;
36 | border: 0;
37 | border-radius: 20px;
38 | align-items: center;
39 | box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.1);
40 | }
41 |
42 | .content {
43 | padding: 20px;
44 | }
45 |
46 | .hospitals_search {
47 | margin: 20px auto;
48 | }
49 |
50 | .searchButton {
51 | margin-left: 100px;
52 | margin-top: 10px;
53 | padding: 6px 30px;
54 | color: white;
55 | background-color: #3fb3d6;
56 | border: 0;
57 | border-radius: 20px;
58 | align-items: center;
59 | box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.1);
60 | }
61 |
62 | /* profile */
63 | .inforWrapper {
64 | display: flex;
65 | flex-direction: column;
66 | width: 80%;
67 | margin-left: auto;
68 | margin-right: auto;
69 | }
70 |
71 | .profileContainer {
72 | background-color: rgb(255, 255, 255);
73 | display: flex;
74 | flex-direction: column;
75 | width: 100%;
76 | border-radius: 8px;
77 | box-shadow: 3px 3px 30px #dadbe4;
78 | }
79 |
80 | .profileRow {
81 | display: flex;
82 | justify-content: space-between;
83 | padding: 2px;
84 | }
85 |
86 | .title {
87 | width: 150px;
88 | text-align: start;
89 | align-items: flex-start;
90 | min-width: 100px;
91 | padding: 10px 12px;
92 | }
93 |
94 | .text {
95 | width: calc(100% - 200px);
96 | padding: 10px 12px;
97 | color: grey;
98 | }
99 |
100 | .horizontal {
101 | width: 95%;
102 | height: 2px;
103 | margin-left: auto;
104 | margin-right: auto;
105 | margin-bottom: 5px;
106 | }
107 |
108 | .col {
109 | display: flex;
110 | flex-direction: column;
111 | }
--------------------------------------------------------------------------------
/src/Screens/Admin/Profile/Profile.module.css:
--------------------------------------------------------------------------------
1 | .hospitals_wrapper {
2 | display: flex;
3 | flex-direction: row;
4 | width: 100%;
5 | height: 100vh;
6 | }
7 |
8 | .main_wrapper {
9 | display: flex;
10 | flex-direction: column;
11 | width: calc(100% - 240px);
12 | overflow: hidden;
13 | overflow-y: scroll;
14 | background-color: #f9fbff;
15 | }
16 |
17 | .navBar {
18 | padding: 15px 50px;
19 | /* padding-top: 25px; */
20 | display: flex;
21 | flex-direction: row;
22 | width: 100%;
23 | align-items: center;
24 | justify-content: space-between;
25 | background-color: rgba(250, 181, 172, 0.61);
26 | }
27 |
28 | .user {
29 | font-size: 20px;
30 | font-weight: 500;
31 | }
32 |
33 | .connectButton {
34 | padding: 6px 30px;
35 | color: white;
36 | background-color: #44b4d9;
37 | border: 0;
38 | border-radius: 20px;
39 | align-items: center;
40 | box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.1);
41 | }
42 |
43 | .content {
44 | padding: 20px;
45 | }
46 |
47 | .hospitals_search {
48 | margin: 20px auto;
49 | }
50 |
51 | .searchButton {
52 | margin-left: 100px;
53 | margin-top: 10px;
54 | padding: 6px 30px;
55 | color: white;
56 | background-color: #d95544;
57 | border: 0;
58 | border-radius: 20px;
59 | align-items: center;
60 | box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.1);
61 | }
62 |
63 | /* profile */
64 | .inforWrapper {
65 | display: flex;
66 | flex-direction: column;
67 | width: 80%;
68 | margin-left: auto;
69 | margin-right: auto;
70 | }
71 |
72 | .profileContainer {
73 | background-color: rgb(255, 255, 255);
74 | display: flex;
75 | flex-direction: column;
76 | width: 100%;
77 | border-radius: 8px;
78 | box-shadow: 3px 3px 30px #dadbe4;
79 | }
80 |
81 | .profileRow {
82 | display: flex;
83 | justify-content: space-between;
84 | padding: 2px;
85 | }
86 |
87 | .title {
88 | width: 150px;
89 | text-align: start;
90 | align-items: flex-start;
91 | min-width: 100px;
92 | padding: 10px 12px;
93 | }
94 |
95 | .text {
96 | width: calc(100% - 200px);
97 | padding: 10px 12px;
98 | color: grey;
99 | }
100 |
101 | .horizontal {
102 | width: 95%;
103 | height: 2px;
104 | margin-left: auto;
105 | margin-right: auto;
106 | margin-bottom: 5px;
107 | }
108 |
109 | .col {
110 | display: flex;
111 | flex-direction: column;
112 | }
--------------------------------------------------------------------------------
/src/Screens/Home/Header.jsx:
--------------------------------------------------------------------------------
1 | import { useState} from "react";
2 | import "./header.css";
3 | import { useSelector } from "react-redux";
4 |
5 | export default function Header() {
6 | const [isNavExpanded, setIsNavExpanded] = useState(false);
7 | const userDetails = useSelector((state) => state.userDetails);
8 |
9 | const { userInfo, loading, error } = userDetails;
10 | let userId = userInfo?.id;
11 | let userRole = userInfo?.user_metadata?.role?.toLowerCase();
12 |
13 | const menus = [
14 | {
15 | name: "Home",
16 | url: "/",
17 | },
18 | {
19 | name: "Recruiter",
20 | url: "/register/hr",
21 | },
22 | {
23 | name: "Admin",
24 | url: "/register/admin",
25 | },
26 | {
27 | name: "About",
28 | url: "/about",
29 | },
30 | {
31 | name: userId && userRole ? "logout" : "login",
32 | url: userId && userRole ? "/logout" : "/login",
33 | },
34 | ];
35 |
36 | return (
37 |
38 |
39 |
44 | TPO VJTI
45 |
46 |
{
49 | setIsNavExpanded(!isNavExpanded);
50 | }}
51 | >
52 |
58 |
63 |
64 |
65 |
70 |
71 | {menus.map(({ name, url }, index) => (
72 |
73 | {name}
74 |
75 | ))}
76 |
77 |
78 |
79 |
80 | );
81 | }
82 |
--------------------------------------------------------------------------------
/src/Screens/Home/header.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Karla:wght@200;400&display=swap");
2 |
3 | .navigation {
4 | position: relative;
5 | display: flex;
6 | align-items: center;
7 | height: 60px;
8 | width: 100%;
9 | padding: 0.5rem 0rem;
10 | background-color: #fff;
11 | color: black;
12 | box-shadow: 0 1px 0px 0px rgba(9, 9, 9, 0.23);
13 | }
14 |
15 | .brand-name {
16 | text-decoration: none;
17 | color: black;
18 | font-size: 1.3rem;
19 | margin-left: 1rem;
20 | }
21 |
22 | .navigation-menu {
23 | margin-left: auto;
24 | }
25 |
26 | .navigation-menu ul {
27 | display: flex;
28 | padding: 0;
29 | }
30 |
31 | .navigation-menu li {
32 | list-style-type: none;
33 | margin: 0 1rem;
34 | border-radius: 10px;
35 |
36 | }
37 |
38 | .navigation-menu li a {
39 | text-decoration: none;
40 | display: block;
41 | width: 100%;
42 | padding: 0.5em 0.7em;
43 | }
44 |
45 | .hamburger {
46 | border: 0;
47 | height: 40px;
48 | width: 40px;
49 | padding: 0.5rem;
50 | border-radius: 50%;
51 | background-color: #283b8b;
52 | cursor: pointer;
53 | transition: background-color 0.2s ease-in-out;
54 | position: absolute;
55 | top: 50%;
56 | right: 25px;
57 | transform: translateY(-50%);
58 | display: none;
59 | }
60 |
61 | .hamburger:hover {
62 | background-color: #2642af;
63 | }
64 |
65 | @media screen and (max-width: 550px) {
66 | .hamburger {
67 | display: block;
68 | }
69 |
70 | .navigation-menu ul {
71 | flex-direction: column;
72 | position: absolute;
73 | top: 60px;
74 | left: 0;
75 | width: 100%;
76 | height: calc(100vh - 60px);
77 | background-color: white;
78 | border-top: 1px solid black;
79 | display: none;
80 | }
81 |
82 | .navigation-menu li {
83 | text-align: center;
84 | margin: 0;
85 | /* padding: 0.5em 0.7em; */
86 | }
87 |
88 | .navigation-menu li a {
89 | color: black;
90 | width: 100%;
91 | padding: 1.5rem 0;
92 | }
93 |
94 | .navigation-menu li:hover {
95 | background-color: rgb(201, 201, 201);
96 | }
97 |
98 | .navigation-menu.expanded ul {
99 | display: block;
100 | }
101 | }
102 |
103 | .container{
104 | margin: 0px auto;
105 | max-width: 1120px;
106 | background-color: #2642af;
107 | }
108 |
109 | .navigation-menu li:last-child{
110 | background-color:#753bd9;
111 | color: white;
112 | border-radius: 10px;
113 | padding: 0.2em 0.5em!important ;
114 | }
115 |
--------------------------------------------------------------------------------
/src/Graphql/Mutations/recruter.js:
--------------------------------------------------------------------------------
1 | import { gql } from '@apollo/client';
2 |
3 | const CREATE_NEW_RECRUTERS_MUTATION = gql`
4 | mutation createNewRecruters($objects: [Recruiters_insert_input!] = []) {
5 | insert_Recruiters(objects: $objects) {
6 | affected_rows
7 | returning {
8 | id
9 | name
10 | email
11 | }
12 | }
13 | }
14 | `;
15 |
16 | const CREATE_NEW_JOB_MUTATION = gql`
17 | mutation createNewJob($newJob: Job_Details_insert_input! = {}) {
18 | insert_Job_Details_one(object: $newJob) {
19 | id
20 | title
21 | Job_Requirements {
22 | id
23 | }
24 | }
25 | }
26 | `;
27 |
28 | const CREATE_NEW_ROUND = gql`
29 | mutation createNewRound($object: Rounds_insert_input!) {
30 | insert_Rounds_one(object: $object) {
31 | id
32 | jobId
33 | companyName
34 | isFinal
35 | roundDetail
36 | roundNo
37 | roundTime
38 | status
39 | shortlistStudentList
40 | }
41 | }`
42 |
43 | const STUDENT_TRANSITION_FOR_NEXT_ROUND = gql`
44 | mutation studentTransitionForNextRound($roundId: bigint = "", $_set: Rounds_set_input = {}) {
45 | update_Rounds_by_pk(pk_columns: {id: $roundId}, _set: $_set) {
46 | id
47 | isFinal
48 | jobId
49 | roundDetail
50 | roundNo
51 | roundTime
52 | shortlistStudentList
53 | }
54 | }`
55 |
56 | // const MARK_FINAL_SELECT_STUDENTS_MUTATION = gql`
57 | // mutation markFinalSelectStudents($applicationsIds: [bigint!] = "", $roundId: bigint = "") {
58 | // update_Applications_many(updates: {where: {id: {_in: $applicationsIds}}, _set: {isSelected: true}}) {
59 | // affected_rows
60 | // }
61 | // update_Rounds(where: {id: {_eq: $roundId}}, _set: {status: "completed"}) {
62 | // affected_rows
63 | // }
64 | // }
65 | // `;
66 |
67 | const MARK_FINAL_REJECT_STUDENTS_MUTATION = gql`
68 | mutation markFinalRejectStudents($jobId:bigint = "") {
69 | update_Applications_many(updates: {where: {jobId: {_eq: $jobId}}, _set: {selectionStatus: -1}}) {
70 | affected_rows
71 | }
72 | }
73 | `;
74 |
75 | const MARK_FINAL_SELECT_STUDENTS_MUTATION = gql`
76 | mutation markFinalSelectStudents($applicationsIds: [bigint!] = "", $roundId: bigint = "") {
77 | update_Applications_many(updates: {where: {id: {_in: $applicationsIds}}, _set: {selectionStatus: 1}}) {
78 | affected_rows
79 | }
80 | update_Rounds(where: {id: {_eq: $roundId}}, _set: {status: "completed"}) {
81 | affected_rows
82 | }
83 | }
84 | `;
85 |
86 | export {
87 | CREATE_NEW_RECRUTERS_MUTATION,
88 | CREATE_NEW_JOB_MUTATION,
89 | CREATE_NEW_ROUND,
90 | STUDENT_TRANSITION_FOR_NEXT_ROUND,
91 | MARK_FINAL_SELECT_STUDENTS_MUTATION,
92 | MARK_FINAL_REJECT_STUDENTS_MUTATION
93 | }
--------------------------------------------------------------------------------
/src/Screens/Admin/Profile/Profile.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import ASidebar from "../../../Components/adminSidebar/ASidebar";
3 | import styles from "./Profile.module.css";
4 | import { useNavigate } from "react-router-dom";
5 | import { supabase } from "../../../Utils/supabase.config";
6 | import { GET_ADMIN_INFO_QUERY } from "../../../Graphql/Mutations/admin";
7 | import { useQuery } from '@apollo/client';
8 |
9 | const ProfileScreen = () => {
10 | const navigate = useNavigate();
11 | const [jobId, setJobId] = useState("");
12 |
13 |
14 | useEffect(() => {
15 | supabase.auth.getSession().then((res) => {
16 | // console.log(res?.data?.session?.user,"resdata");
17 | setJobId(res?.data?.session?.user?.id)
18 | // console.log(res?.data?.session?.user?.id)
19 |
20 | const role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
21 | });
22 |
23 | }, []);
24 |
25 | const { loading, error, data } = useQuery(GET_ADMIN_INFO_QUERY, {
26 | variables: { "id": jobId }
27 | });
28 |
29 |
30 | // console.log(data, "data")
31 | return (
32 |
33 |
34 |
35 |
36 |
Welcome {}!
37 |
38 |
39 |
40 |
41 | Profile Information
42 |
43 |
44 |
70 |
71 |
72 |
73 | );
74 | };
75 |
76 | export default ProfileScreen;
77 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import { BrowserRouter, Route, Routes } from 'react-router-dom';
2 | import './App.css';
3 | import RegisterHR from './Screens/HR/RegisterHr/RegisterHR';
4 | import RegisterAdmin from './Screens/Admin/RegisterAdmin/RegisterAdmin';
5 | import CreateJob from './Screens/HR/CreateJob/CreateJob';
6 | import TpoPolicy from './Screens/Admin/TpoPolicy/TpoPolicy';
7 | import ProfileScreen from './Screens/Admin/Profile/Profile';
8 | import HRProfileScreen from './Screens/HR/Profile/Profile';
9 | import Login from './Screens/Login/Login';
10 | import Logout from './Screens/Logout';
11 | import AdminDashboard from './Screens/Admin/Dashboard/Dashboard';
12 | import ViewStudents from './Screens/Admin/ViewStudents/ViewStudents';
13 | import PastJobs from './Screens/HR/PastJobs/PastJobs';
14 | import Job from './Screens/HR/Job';
15 | import ApplicantList from './Screens/HR/ApplicantList';
16 | import RoundDetails from './Screens/HR/RoundDetail';
17 | import Schedule from './Screens/Admin/Schedule';
18 | import CreateRound from './Screens/HR/CreateRound';
19 | import Error from './Screens/Error';
20 | import MainHome from './Screens/Home/MainHome';
21 | import PrivateRoute from './Utils/PrivateOutlet';
22 | import About from './Screens/Home/About';
23 |
24 |
25 | function App() {
26 | return (
27 |
28 |
29 |
30 | } />
31 | } />
32 | } />
33 | } />
34 | } />
35 |
36 | {/* hr routes goes here */}
37 |
38 | }>
39 | } />
40 | } />
41 | } />
42 |
43 | } />
44 | } >
45 | } />
46 | } />
47 | } />
48 |
49 |
50 | } />
51 |
52 |
53 | {/* admin routes goes here */}
54 |
55 | }>
56 | } />
57 | } />
58 | } />
59 | } />
60 | } />
61 | } />
62 |
63 |
64 |
65 | } />
66 |
67 |
68 |
69 | );
70 | }
71 |
72 | export default App;
73 |
--------------------------------------------------------------------------------
/src/actions/userActions.js:
--------------------------------------------------------------------------------
1 | import { supabase } from "../Utils/supabase.config"
2 | import { ADMIN_REGISTER_FAIL, ADMIN_REGISTER_REQUEST, ADMIN_REGISTER_SUCCESS, ADMIN_LOGIN_REQUEST, ADMIN_LOGIN_FAIL, ADMIN_LOGIN_SUCCESS, ADMIN_LOGOUT, ADMIN_DETAILS_FAIL, ADMIN_DETAILS_REQUEST, ADMIN_DETAILS_SUCCESS } from "../constants/userConstants"
3 |
4 | export const register = ({ firstName, middleName, lastName, gender, dob, email, password, role }) => async (dispatch) => {
5 | try {
6 | dispatch({
7 | type: ADMIN_REGISTER_REQUEST,
8 | })
9 |
10 |
11 | const { data, error } = await supabase.auth.signUp({
12 | email,
13 | password,
14 | options: {
15 | data: {
16 | role
17 | },
18 | },
19 | });
20 |
21 |
22 | dispatch({
23 | type: ADMIN_REGISTER_SUCCESS,
24 | payload: data,
25 | })
26 |
27 | } catch (error) {
28 | dispatch({
29 | type: ADMIN_REGISTER_FAIL,
30 | payload:
31 | error.response && error.response.data.message
32 | ? error.response.data.message
33 | : error.message,
34 | })
35 | }
36 | }
37 |
38 | export const login = (email, password) => async (dispatch) => {
39 | try {
40 | dispatch({
41 | type: ADMIN_LOGIN_REQUEST,
42 | })
43 |
44 |
45 | const { data } = await supabase.auth.signInWithPassword({
46 | email, password
47 | })
48 |
49 | console.log("DATA : ", data?.session);
50 | dispatch({
51 | type: ADMIN_LOGIN_SUCCESS,
52 | payload: data?.session,
53 | })
54 |
55 | } catch (error) {
56 | dispatch({
57 | type: ADMIN_LOGIN_FAIL,
58 | payload:
59 | error.response && error.response.data.message
60 | ? error.response.data.message
61 | : error.message,
62 | })
63 | }
64 | }
65 |
66 | export const logout = () => async (dispatch) => {
67 | try {
68 | const { data } = await supabase.auth.signOut()
69 | } catch (error) {
70 | console.log(error);
71 | }
72 |
73 | dispatch({ type: ADMIN_LOGOUT })
74 |
75 | document.location.href = '/login'
76 | }
77 |
78 | export const getUserDetails = () => async (dispatch) => {
79 | try {
80 | dispatch({
81 | type: ADMIN_DETAILS_REQUEST,
82 | })
83 |
84 | const { data } = await supabase.auth.getUser()
85 | // console.log("getUserDetails ", data);
86 | dispatch({
87 | type: ADMIN_DETAILS_SUCCESS,
88 | payload: data?.user ?? "undefined",
89 | })
90 | } catch (error) {
91 | const message =
92 | error.response && error.response.data.message
93 | ? error.response.data.message
94 | : error.message
95 | if (message === 'Not authorized, token failed') {
96 | dispatch(logout())
97 | }
98 | dispatch({
99 | type: ADMIN_DETAILS_FAIL,
100 | payload: message,
101 | })
102 | }
103 | }
--------------------------------------------------------------------------------
/src/Graphql/Queries/recruiter.js:
--------------------------------------------------------------------------------
1 | import { gql } from "@apollo/client";
2 |
3 | const GET_RECRUITER_INFO = gql`
4 | query getRecruterInfo($_eq: uuid = "") {
5 | Recruiters(where: {id: {_eq: $_eq}}) {
6 | id
7 | email
8 | mobileNo
9 | companyName
10 | name
11 | created_at
12 |
13 | }
14 | }
15 | `;
16 |
17 |
18 | const GET_JOB_CREATED_BY_RECRUTER_QUERY = gql`
19 | query getJobCreatedByRecruter($_eq: uuid = "") {
20 | Job_Details(where: {recruterId: {_eq: $_eq}}, order_by: {updated_at: desc}) {
21 | id
22 | locations
23 | noOfRounds
24 | salary
25 | title
26 | description
27 | companyName
28 | recruterId
29 | }
30 | }
31 | `;
32 |
33 | const GET_APPLICANT_LIST_BY_JOB_ID_QUERY = gql`
34 | query getApplicantListByJobId($jobId: bigint = "") {
35 | Applications(where: {jobId: {_eq: $jobId}}, order_by: {insertted_at: desc}) {
36 | id
37 | isAccepted
38 | selectionStatus
39 | resumeLink
40 | Student {
41 | id
42 | CPI
43 | branch
44 | clgEmail
45 | gender
46 | clgId
47 | firstName
48 | middleName
49 | lastName
50 | mobileNumber
51 | column_12th
52 | gradYear
53 | resumeLink
54 | programme
55 | personalEmail
56 | }
57 | }
58 | }
59 | `;
60 |
61 | const GET_ALL_DETAILS_OF_ONE_ROUND_QUERY = gql`
62 | query getAllDetailsOfOneRound($roundId: bigint = "") {
63 | Rounds_by_pk(id: $roundId) {
64 | id
65 | jobId
66 | companyName
67 | isFinal
68 | roundDetail
69 | roundNo
70 | roundTime
71 | status
72 | shortlistStudentList
73 | }
74 | }
75 | `;
76 | const GET_JOB_INFO_BY_JOBID_QUERY = gql`
77 | query getJobInfoByJobId($id: bigint = "") {
78 | Job_Details_by_pk(id: $id) {
79 | companyName
80 | description
81 | endDateToApply
82 | id
83 | locations
84 | recruterId
85 | noOfRounds
86 | salary
87 | title
88 | }
89 | }
90 | `;
91 |
92 | const GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY = gql`
93 | query getRoundsInfoByApplicationid($applicationId: bigint = "") {
94 | Rounds(where: {jobId: {_eq: $applicationId}}, order_by: {inserted_at: asc}) {
95 | id
96 | jobId
97 | companyName
98 | isFinal
99 | roundDetail
100 | roundNo
101 | roundTime
102 | status
103 | shortlistStudentList
104 | }
105 | }
106 | `;
107 |
108 |
109 | const GET_STUDENTS_DETAILS_FRO_EACH_ROUND_QUERY = gql`
110 | query getStudentsDetailsFroEachRound($jobId: bigint = "", $applicationIds: [bigint!] = []) {
111 | Applications(where: {jobId: {_eq: $jobId}, id: {_in: $applicationIds}}) {
112 | id
113 | resumeLink
114 | selectionStatus
115 | Student {
116 | CPI
117 | branch
118 | clgEmail
119 | clgId
120 | firstName
121 | gradYear
122 | gender
123 | id
124 | isCr
125 | isDreamPlaced
126 | isNormalPlaced
127 | isSuperPlaced
128 | lastName
129 | middleName
130 | mobileNumber
131 | programme
132 | resumeLink
133 | personalEmail
134 | }
135 | }
136 | }
137 | `;
138 |
139 | export {
140 | GET_RECRUITER_INFO,
141 | GET_JOB_CREATED_BY_RECRUTER_QUERY,
142 | GET_ALL_DETAILS_OF_ONE_ROUND_QUERY,
143 | GET_APPLICANT_LIST_BY_JOB_ID_QUERY,
144 | GET_JOB_INFO_BY_JOBID_QUERY,
145 | GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY,
146 | GET_STUDENTS_DETAILS_FRO_EACH_ROUND_QUERY
147 | }
--------------------------------------------------------------------------------
/src/Screens/Admin/Dashboard/Dashboard.jsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import {
3 | Container,
4 | Typography,
5 | Grid,
6 | } from "@mui/material";
7 | import DashboardCard from "../../../Components/dashboard/DashboardCard";
8 | import DashboardTable from "../../../Components/dashboard/DashboardTable";
9 | import DashboardHeading from "../../../Components/dashboard/DashboardHeading";
10 | import ASidebar from "../../../Components/adminSidebar/ASidebar";
11 |
12 | function createData(
13 | name,
14 | ctc,
15 | students
16 | ) {
17 | return { name, ctc, students };
18 | }
19 |
20 | var dashboardData= {
21 | "overview":[
22 | {"desc":"Total companies",
23 | "value":300,
24 | "color_val": "#8cf0f5"},
25 | {"desc":"Total students registered",
26 | "value": 4000,
27 | "color_val": "#5fd986"}
28 | ],
29 | "students":{
30 | "placements":[
31 | {"desc":"Students registered",
32 | "value": 2000,
33 | "color_val": "#9d83f2"},
34 | {"desc":"Students placed",
35 | "value": 1800,
36 | "color_val": "#f5a262"},
37 | {"desc":"Highest CTC",
38 | "value": "50 LPA",
39 | "color_val": "#e0f57a"}
40 | ],
41 | "internships":[
42 | {"desc":"Students registered",
43 | "value":2000,
44 | "color_val": "#5f65d4"},
45 | {"desc":"Students placed",
46 | "value": 1900,
47 | "color_val": "#96d4a3"},
48 | {"desc":"Highest stipend (per month)",
49 | "value": "3 Lac",
50 | "color_val": "#f7adea"}
51 | ]
52 | },
53 | "topRecruiters": [
54 | createData('DE Shaw', 62, 1),
55 | createData('Wells Fargo', 24, 15),
56 | createData('Deutche Bank', 19, 11),
57 | ]
58 | }
59 |
60 | const AdminDashboard = () => {
61 |
62 | return (
63 |
64 |
65 |
66 |
67 |
75 | Admin Dashboard
76 |
77 |
78 |
79 |
80 |
81 | {dashboardData.overview.map((row)=>(
82 | ))}
83 |
84 |
85 |
86 |
87 | {dashboardData.students.placements.map((row)=>(
88 | ))}
89 |
90 |
91 |
92 |
93 | {dashboardData.students.internships.map((row)=>(
94 | ))}
95 |
96 |
97 |
98 |
99 |
100 | );
101 | };
102 |
103 | export default AdminDashboard;
104 |
--------------------------------------------------------------------------------
/src/Screens/HR/PastJobs/PastJobs.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Sidebar from '../../../Components/hrSidebar/Sidebar'
3 | import { useNavigate } from "react-router-dom";
4 | import { supabase } from "../../../Utils/supabase.config";
5 | import { useEffect, useState } from "react";
6 | import { useQuery } from '@apollo/client';
7 | import { GET_JOB_CREATED_BY_RECRUTER_QUERY, GET_RECRUITER_INFO } from '../../../Graphql/Queries/recruiter';
8 | import styles from "../CreateJob/CreateJob.module.css"
9 |
10 |
11 | const JobCard = ({companyName,description,salary,id,title}) => {
12 | const navigate = useNavigate();
13 | let desc=description.split(/\s+/).slice(0, 10).join(" ");
14 | return (
15 |
16 |
17 |
18 |
{companyName} : {title}
19 |
20 | Description: {desc}
21 |
22 |
23 |
24 | Salary : {salary}
25 |
26 |
{
29 | e.preventDefault();
30 | navigate(
31 | `/hr/createdjobs/${id}`
32 | );
33 | }}>
34 | View Job
35 |
36 |
37 |
38 | )
39 | }
40 |
41 |
42 |
43 | const PastJobs = () => {
44 | const navigate = useNavigate();
45 | const [jobId, setJobId] = useState("");
46 | const [userInfo, setUserInfo] = useState("");
47 | const { jobsLoading, error, data } = useQuery(GET_JOB_CREATED_BY_RECRUTER_QUERY, {
48 | variables: { "_eq": jobId }
49 | });
50 |
51 |
52 | useEffect(() => {
53 | const role = "";
54 | supabase.auth.getSession().then((res) => {
55 | if (res?.data?.session?.user) {
56 | setJobId(res?.data?.session?.user?.id)
57 | console.log(res?.data?.session?.user?.id,"console")
58 | }
59 | else navigate("/login");
60 | setUserInfo(res?.data?.session?.user?.id);
61 |
62 | const role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
63 | console.log(role);
64 | if (role && role != "hr") navigate(`/${role}`);
65 | });
66 |
67 |
68 | }, [jobId]);
69 |
70 | return (
71 |
72 |
73 |
74 |
Previous Jobs
75 |
76 | {
77 | data?.Job_Details.length == 0 ?
No Previous jobs exits...
: ""
78 | }
79 | {data?.Job_Details.map((job, index) => (
80 |
81 | ))}
82 |
83 |
84 |
85 |
86 | )
87 |
88 | }
89 |
90 | export default PastJobs
91 |
92 |
93 |
--------------------------------------------------------------------------------
/src/Screens/HR/Profile/Profile.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import Sidebar from "../../../Components/hrSidebar/Sidebar";
3 | import styles from "./Profile.module.css";
4 | import { useNavigate } from "react-router-dom";
5 | import { supabase } from "../../../Utils/supabase.config";
6 | import { useQuery } from "@apollo/client";
7 | import { GET_RECRUITER_INFO } from "../../../Graphql/Queries/recruiter";
8 |
9 | const HRProfileScreen = () => {
10 | const navigate = useNavigate();
11 | const [jobId, setJobId] = useState("");
12 |
13 | useEffect(() => {
14 | const role = "";
15 | supabase.auth.getSession().then((res) => {
16 | if (res?.data?.session?.user) {
17 | setJobId(res?.data?.session?.user?.id);
18 | } else navigate("/login");
19 | let role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
20 | console.log(role);
21 | if (role && role != "hr") navigate(`/${role}`);
22 | });
23 | }, []);
24 |
25 | const {
26 | loading: rloading,
27 | error: rerror,
28 | data: recruterData,
29 | } = useQuery(GET_RECRUITER_INFO, {
30 | variables: { _eq: jobId },
31 | });
32 |
33 | // console.log(recruterData?.Recruiters[0], "data")
34 | if (rloading)
35 | return (
36 |
44 | );
45 |
46 | return (
47 |
48 |
49 |
50 |
51 |
52 | Welcome {recruterData?.Recruiters[0]?.name}!
53 |
54 |
55 |
56 |
57 |
58 | Profile Information
59 |
60 |
61 |
62 |
63 |
64 |
65 | NAME : {" "}
66 | {recruterData?.Recruiters[0]?.name}{" "}
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | EMAIL : {" "}
75 | {recruterData?.Recruiters[0]?.email}{" "}
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | MOBILE : {" "}
84 | {recruterData?.Recruiters[0]?.mobileNo}{" "}
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | COMPANY : {" "}
93 | {recruterData?.Recruiters[0]?.companyName}{" "}
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | );
103 | };
104 |
105 | export default HRProfileScreen;
106 |
--------------------------------------------------------------------------------
/src/Screens/Home/MainHome.module.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Karla:wght@200;400&display=swap");
2 |
3 | .container{
4 | margin: 10px auto;
5 | max-width: 1140px;
6 | }
7 |
8 | .row{
9 | display: flex;
10 | justify-content: space-between;
11 | margin-top: 5px;
12 | }
13 |
14 | .info{
15 | background: linear-gradient(120deg,#fff,#f99fb6);
16 | padding: 1em;
17 | }
18 |
19 | .hero{
20 | text-align: center;
21 | display: flex;
22 | flex-direction: column;
23 | justify-content: space-between;
24 | max-width: 650px;
25 | padding: 6em 1em 2em 1em;
26 | }
27 | .hero > h1{
28 | font-size: xx-large;
29 | margin: 1em 0;
30 | font-weight: 300;
31 | letter-spacing: 1.2px;
32 | }
33 | .hero > p{
34 | font-size: large;
35 | margin: 1em 0;
36 | font-weight: 400;
37 | }
38 |
39 | .btn {
40 | display: inline-block;
41 | text-decoration: none;
42 | text-transform: uppercase;
43 | color: #fff;
44 | background-color: rgb(221, 217, 238);
45 | padding: .75em 2em;
46 | border-radius: 10px;
47 | min-width: 30%;
48 | margin: 5px auto;
49 | }
50 |
51 | .btn:hover,
52 | .btn:focus {
53 | opacity: .75;
54 | }
55 |
56 | .features{
57 | height: auto;
58 | margin: 30px auto;
59 | padding: 1em;
60 | }
61 |
62 | .features button{
63 | display: inline-block;
64 | text-decoration: none;
65 | text-transform: capitalize;
66 | color: var(--white);
67 | background-color: var(--black);
68 | padding: .23em 0.3em;
69 | border-radius: 10px;
70 | margin: 5px 0 10px 0;
71 | font-size: 1em;
72 | }
73 | .features h3{
74 | display: block;
75 | text-decoration: none;
76 | text-transform: capitalize;
77 | margin: 5px 1px;
78 | font-size: xx-large;
79 | }
80 | .features p{
81 | display: block;
82 | text-decoration: none;
83 | color: grey;
84 | padding: 0.5em;
85 | margin: 5px;
86 | /* max-width: 50%; */
87 | }
88 | .features .features__flex{
89 | display: flex;
90 | flex-direction: row;
91 | justify-content: space-between;
92 | flex-wrap: wrap;
93 | margin-top: 3rem;
94 |
95 | }
96 |
97 | .feature_card{
98 | display: flex;
99 | flex-direction: column;
100 | justify-content: space-around;
101 | padding: 0.5em 0.8em;
102 | /* height: 4em; */
103 | box-shadow: 1px 1px 10px lightgrey;
104 | margin: 5px;
105 | width: 31%;
106 | border-radius: 10px;
107 | }
108 |
109 | .features .feature_card h3{
110 | display: block;
111 | text-decoration: none;
112 | text-transform: capitalize;
113 | margin: 5px 1px;
114 | font-size: x-large;
115 | align-self: center;
116 | }
117 |
118 | .feature_card h4{
119 | display: block;
120 | text-decoration: none;
121 | text-transform: capitalize;
122 | margin: 5px 1px;
123 | font-size: large;
124 | align-self: center;
125 | color: rgb(128, 120, 120);
126 | }
127 |
128 | .feature_card p{
129 | display: block;
130 | text-decoration: none;
131 | text-transform: capitalize;
132 | color: rgb(128, 120, 120);
133 | font-size: x-medium;
134 | margin: 5px;
135 | align-self: center;
136 | width: 100% !important;
137 | }
138 | .features .feature_card a{
139 | display: block;
140 | text-decoration: none;
141 | text-transform: capitalize;
142 | color: grey;
143 | margin: 5px;
144 | color: rgb(221, 217, 238);
145 | }
146 | .features .feature_card .icon{
147 | display: block;
148 | text-decoration: none;
149 | text-transform: capitalize;
150 | color: grey;
151 | margin: 5px;
152 | color: var(--black);
153 | align-self: center;
154 | }
155 |
156 | @media (max-width:610px)
157 | {
158 | .features .features__flex{
159 | flex-direction: column;
160 | }
161 |
162 | .feature_card{
163 | margin: 5px;
164 | width: 100%;
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/Screens/Home/MainHome.jsx:
--------------------------------------------------------------------------------
1 | import { Box } from "@mui/material";
2 | import Header from "./Header";
3 | import styles from "./MainHome.module.css";
4 | import PersonIcon from "@mui/icons-material/Person";
5 | import GroupIcon from '@mui/icons-material/Group';
6 | import PersonAddIcon from '@mui/icons-material/PersonAdd';
7 |
8 | const AdminD = [
9 | "● Create company schedule",
10 | "● Invite Companies",
11 | "● Manage CRs ",
12 | ];
13 | const studentD = [
14 | "● Apply for eligible jobs",
15 | "● View daily placement updates ",
16 | "● Generate Resumes",
17 | ];
18 | const RecruiterD = ["● Create new Job Postings", "● Access created jobs","● Post selection roundwise"];
19 |
20 | const MainHome = () => {
21 | const Footer = () => {
22 | return (
23 | <>
24 |
33 | theme.palette.mode === "light"
34 | ? theme.palette.grey[200]
35 | : theme.palette.grey[800],
36 | }}
37 | >
38 |
39 | TPO VJTI 2023 © - All Rights Reserved.
40 |
41 |
42 | >
43 | );
44 | };
45 |
46 | const CustomButton = ({ text, color = "#753bd9" }) => {
47 | return (
48 |
52 | {text}
53 |
54 | );
55 | };
56 |
57 | const FeatureCard = ({ name, text, icon, url = "#" }) => {
58 | return (
59 |
60 |
{icon}
61 |
{name}
62 | {text.map(function (name, index) {
63 | return
{name}
;
64 | })}
65 |
see more..
66 |
67 | );
68 | };
69 |
70 | return (
71 | <>
72 |
73 |
74 |
75 | Digitalizing Recruitment
76 |
77 |
78 | Our Recruitment portal
79 | {" "}
80 | is designed to keep track of all the records of the students, companies , TPO and provide them a smart platform to interact with each other.
81 | Our goal is to reduce the reliance on manual processes, streamline the processes of the Recruitment to minimize the amount of time and effort required .
82 |
83 |
84 |
85 |
86 |
87 |
88 |
95 | Key Features
96 |
97 |
Our three roles!
98 | {/*
99 | Our application provides a central repository of data
100 | comprising all the tests and other medical processes a
101 | patient went through, it reduces the scope of
102 | duplication of the same processes and thus prevents
103 | delay in the treatment. This data of patients can be
104 | used by hospitals to provide blood and other medical
105 | services to needy patients. patients have the power to
106 | provide their data to research organization so that they
107 | can research and develop solutions to medical problems.
108 |
*/}
109 |
110 |
115 | }
116 | name="Admin"
117 | text={AdminD}
118 | url="/"
119 | />
120 |
125 | }
126 | name="Recruiter"
127 | text={RecruiterD}
128 | url="/"
129 | />
130 |
135 | }
136 | name="Student"
137 | text={studentD}
138 | url="/"
139 | />
140 |
141 |
142 |
143 |
144 |
145 | >
146 | );
147 | };
148 |
149 | export default MainHome;
--------------------------------------------------------------------------------
/src/Screens/Home/About.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Header from './Header';
3 | import styles from "./MainHome.module.css";
4 | import { Box } from "@mui/material";
5 |
6 | const FeatureCard = ({ name, text, icon, role }) => {
7 | return (
8 |
9 |
10 |
{name}
11 |
{role}
12 |
{text}
13 |
14 | );
15 | };
16 |
17 | const Footer = () => {
18 | return (
19 | <>
20 |
29 | theme.palette.mode === "light"
30 | ? theme.palette.grey[200]
31 | : theme.palette.grey[800],
32 | }}
33 | >
34 |
35 | TPO VJTI 2023 © - All Rights Reserved.
36 |
37 |
38 | >
39 | );
40 | };
41 |
42 | const About = () => {
43 | return (
44 |
45 |
46 |
47 |
48 | Team Code_Miners
49 |
50 |
51 | This Recruitment portal
52 | {" "}
53 | is our project in the Digital Campus Hackathon (DCH) on the occasion of the centenary year at VJTI 2023.We are the winners of the Digital Campus hackathon under the Administrative track.
54 |
55 |
56 |
57 |
58 |
59 |
69 | Our Team
70 |
71 |
72 |
73 |
74 |
75 |
81 |
82 |
89 |
90 |
97 |
98 |
105 |
106 |
113 |
114 |
121 |
122 |
123 |
124 |
125 |
126 | )
127 | }
128 |
129 | export default About
--------------------------------------------------------------------------------
/src/Screens/Login/Login.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useDispatch } from "react-redux";
3 | import { useNavigate } from "react-router-dom";
4 | import { getUserDetails } from "../../actions/userActions";
5 | import { supabase } from "../../Utils/supabase.config";
6 |
7 | const Login = () => {
8 | const navigate = useNavigate();
9 | const [userInfo, setUserInfo] = useState("");
10 | const dispatch = useDispatch();
11 |
12 | useEffect(() => {
13 | const role = "";
14 | supabase.auth.getSession().then((res) => {
15 | if (res?.data?.session?.user) setUserInfo(res?.data?.session);
16 | role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
17 | console.log("res ", res);
18 | if (role) navigate(`/${role}`);
19 | });
20 |
21 | dispatch(getUserDetails());
22 | // const role = userDetailInfo?.user?.user_metadata?.role;
23 | // console.log(role);
24 | // if (role) navigate(`/${role}`);
25 | }, []);
26 |
27 | const [email, setEmail] = useState("");
28 | const [password, setPassword] = useState("");
29 | const [role, setRole] = useState("admin");
30 |
31 | const handleSubmit = async (e) => {
32 | e.preventDefault();
33 |
34 | console.log(email, password, role);
35 | if (!(email && password && role)) {
36 | return alert("fill all fields");
37 | }
38 |
39 | const { data, error } = await supabase.auth.signInWithPassword({
40 | email,
41 | password,
42 | });
43 | if (
44 | data?.session?.user?.user_metadata?.role?.toLowerCase() ==
45 | role.toLowerCase()
46 | ) {
47 | const role = data?.session?.user?.user_metadata?.role?.toLowerCase();
48 | dispatch(getUserDetails());
49 |
50 | setTimeout(() => {
51 | //reset
52 | setEmail("");
53 | setPassword("");
54 | setRole("admin");
55 | navigate(`/${role}`);
56 | }, 1000);
57 | } else alert("somthing went wrong!!");
58 | };
59 |
60 | return (
61 |
136 | );
137 | };
138 |
139 | export default Login;
140 |
--------------------------------------------------------------------------------
/src/Screens/HR/Job.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { Outlet, useParams } from "react-router";
3 | import { Link } from "react-router-dom";
4 | import Sidebar from "../../Components/hrSidebar/Sidebar";
5 | import {
6 | GET_JOB_INFO_BY_JOBID_QUERY,
7 | GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY,
8 | } from "../../Graphql/Queries/recruiter";
9 | import { useQuery } from "@apollo/client";
10 | import styles from "./CreateJob/CreateJob.module.css";
11 | import { useDispatch, useSelector } from "react-redux";
12 | import { getAllRoundsDetails } from "../../actions/interviewRoundActions";
13 | import Loader from "../../Components/Loader";
14 |
15 | const Job = () => {
16 | const { jobId } = useParams();
17 | // const [rounds, setRounds] = useState([]);
18 | const dispatch = useDispatch();
19 |
20 | const interviewRounds = useSelector((state) => state.interviewRounds);
21 | const {
22 | rounds,
23 | loading: interviewRoundsLoading,
24 | error: interviewRoundsError,
25 | } = interviewRounds;
26 |
27 | const { loading, error, data } = useQuery(GET_JOB_INFO_BY_JOBID_QUERY, {
28 | variables: { id: jobId },
29 | });
30 |
31 | // const { error: eError } = useQuery(GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY, {
32 | // onCompleted: (data) => setRounds(data.Rounds),
33 | // variables: {
34 | // applicationId: jobId,
35 | // },
36 | // });
37 |
38 | useEffect(() => {
39 | dispatch(getAllRoundsDetails(jobId));
40 | }, [dispatch, jobId]);
41 |
42 | if (error) return error
;
43 |
44 | if (loading) return ;
45 |
46 | return (
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | {data?.Job_Details_by_pk?.title}
59 |
60 |
61 |
62 | {data?.Job_Details_by_pk?.description}
63 |
64 |
65 | Salary : {data?.Job_Details_by_pk?.salary}
66 |
67 |
68 |
69 |
70 |
71 |
72 | {interviewRoundsLoading ? (
73 |
74 | ) : (
75 |
76 |
77 |
78 |
82 | Applicant List
83 |
84 |
85 |
86 | {rounds &&
87 | rounds.map(({ id, roundNo }, index) => {
88 | return (
89 |
90 |
94 | Round : {roundNo}
95 |
96 |
97 | );
98 | })}
99 |
100 |
104 | Total Rounds : {rounds?.length ? rounds?.length : 0}
105 |
106 |
107 | {rounds?.[rounds.length - 1]?.isFinal ? (
108 | ""
109 | ) : (
110 |
111 |
115 | Create New Round
116 |
117 |
118 | )}
119 |
120 | {/*
*/}
121 |
122 |
123 | )}
124 |
127 |
128 |
129 |
130 | );
131 | };
132 |
133 | export default Job;
134 |
--------------------------------------------------------------------------------
/src/Screens/HR/PastJobs/ApplicantListTable/ApplicantListTable.jsx:
--------------------------------------------------------------------------------
1 | // import React, { useEffect, useState } from "react";
2 | // import {
3 | // Container,
4 | // Typography,
5 | // Button,
6 | // Table,
7 | // TableBody,
8 | // TableCell,
9 | // TableContainer,
10 | // TableHead,
11 | // TableRow,
12 | // Paper,
13 | // Checkbox,
14 | // Grid,
15 | // } from "@mui/material";
16 | // import { useParams } from "react-router";
17 |
18 |
19 | // import { Link } from "react-router-dom";
20 | // import RoundHeaderCard from "../../../../Components/Rounds/RoundsHeaderCard";
21 |
22 | // const ApplicantListTable = ({
23 | // applications,
24 | // updatedSelects,
25 | // setUpdatedSelects,
26 | // updateApplication,
27 | // title,
28 | // roundAttrs,
29 | // }) => {
30 |
31 | // const requiredArray = ['roundDetail', 'roundTime', 'status']
32 | // const { jobId, roundId } = useParams();
33 |
34 | // console.log(roundId);
35 |
36 | // // const roundAttrs= Object.entries(roundInfo).map(([key, value]) => ({key,value}));
37 | // return (
38 | //
39 | //
48 | // {title}
49 | //
50 | //
51 | // {roundAttrs.map((row, index) => {
52 | // if(!requiredArray.includes(row.key))
53 | // return ( )
54 |
55 | // return(
56 | //
61 | //
)
62 | // })}
63 | //
64 | // {applications ? (
65 | //
66 | //
70 | //
71 | //
72 | // Student Name
73 | //
74 | // Is Selected
75 | //
76 | // {/* Programme */}
77 | // Branch
78 | // {/*
79 | // ID
80 | //
81 | //
82 | // Grad Year
83 | // */}
84 | //
85 | // Gender
86 | //
87 | //
88 | // CPI
89 | //
90 | // {/*
91 | // 10th
92 | //
93 | //
94 | // 12th
95 | // */}
96 | //
97 | // Mobile
98 | //
99 | //
100 | // Resume Link
101 | //
102 | //
103 | //
104 | //
105 | // {applications.map((row, index) => (
106 | //
110 | //
111 | // {row.Student.firstName + " " + row.Student.lastName}
112 | //
113 | //
114 | // {
117 | // var newApplicationAttr = { isSelected: !row.isSelected }; //...students[index],
118 | // updateApplication(row.id, newApplicationAttr);
119 | // var updatedSelects_ = updatedSelects;
120 | // updatedSelects_[row.id] = applications[index].isSelected;
121 | // setUpdatedSelects(updatedSelects_);
122 | // console.log(updatedSelects_);
123 | // }}
124 | // color="success"
125 | // />
126 | //
127 | // {row.Student.branch ? row.Student.branch : "N/A"}
128 |
129 | // {row.Student.gender ? row.Student.gender : "N/A"}
130 | //
131 | // {row.Student.CPI ? row.Student.CPI : "N/A"}
132 | //
133 |
134 | //
135 | // {row.Student.mobileNumber ? row.Student.mobileNumber : "N/A"}
136 | //
137 | //
138 | // {row.resumeLink ? (
139 | //
142 | // ) : (
143 | // "N/A"
144 | // )}
145 | //
146 | //
147 | // ))}
148 | //
149 | //
150 | //
151 | // ) : (
152 | // "Loading..."
153 | // )}
154 | //
155 | // );
156 | // };
157 |
158 | // export default ApplicantListTable;
159 |
--------------------------------------------------------------------------------
/src/Screens/Admin/TpoPolicy/TpoPolicy.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { supabase } from "../../../Utils/supabase.config";
3 | import { useNavigate } from "react-router-dom";
4 | import ASidebar from "../../../Components/adminSidebar/ASidebar";
5 | import styles from "./TpoPolicy.module.css"
6 |
7 | const TpoPolicy = () => {
8 |
9 | const navigate = useNavigate();
10 | const [userInfo, setUserInfo] = useState("");
11 |
12 | useEffect(() => {
13 |
14 | const role = "";
15 | supabase.auth.getSession().then((res) => {
16 | if (res?.data?.session?.user) setUserInfo(res?.data?.session);
17 | else navigate("/login");
18 | role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
19 | if (role && role != "admin") navigate(`/${role}`);
20 | });
21 | }, []);
22 |
23 | const [academicYear, setAcademicYear] = useState("");
24 | const [circuitNormal, setCircuitNormal] = useState("");
25 | const [circuitDream, setCircuitDream] = useState("");
26 |
27 | const [nonCircuitNormal, setNonCircuitNormal] = useState("");
28 | const [nonCircuitDream, setNonCircuitDream] = useState("");
29 |
30 | const handleSubmit = (e) => {
31 | if (!(academicYear && circuitDream && circuitNormal && nonCircuitDream && nonCircuitNormal))
32 | return alert("All fields required");
33 |
34 | e.preventDefault();
35 |
36 | };
37 |
38 | return (
39 |
40 |
41 |
42 |
43 |
TPO Policy
44 |
157 |
158 |
159 |
160 | );
161 | };
162 |
163 | export default TpoPolicy;
164 |
--------------------------------------------------------------------------------
/src/Screens/HR/RegisterHr/RegisterHR.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { useMutation } from "@apollo/client";
4 | import { supabase } from "../../../Utils/supabase.config";
5 | import { CREATE_NEW_RECRUTERS_MUTATION } from "../../../Graphql/Mutations/recruter";
6 |
7 | const RegisterHR = () => {
8 | const [name, setName] = useState("");
9 | const [companyName, setCompanyName] = useState("");
10 | const [emailId, setEmailId] = useState("");
11 | const [mobileNo, setMobileNo] = useState("");
12 | const [password, setPassword] = useState("");
13 |
14 | const [hrRegister, { hrData, loading, hrError }] = useMutation(
15 | CREATE_NEW_RECRUTERS_MUTATION
16 | );
17 |
18 | const navigate = useNavigate();
19 | useEffect(() => {
20 | supabase.auth.getSession().then((res) => {
21 | const role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
22 | if (role) navigate(`/${role}`);
23 | else if (res?.data?.session?.user) navigate(-1);
24 | });
25 | }, []);
26 |
27 | const handleSubmit = async (e) => {
28 | e.preventDefault();
29 | console.log(name, companyName, emailId, mobileNo, password);
30 | if (!(name && companyName && emailId && mobileNo && password))
31 | return alert("All fields required");
32 |
33 | const { data, error } = await supabase.auth.signUp({
34 | email: emailId,
35 | password: password,
36 | options: {
37 | data: {
38 | role: "hr",
39 | },
40 | },
41 | });
42 |
43 | if (error) {
44 | return alert("Something went wrong...");
45 | } else {
46 | hrRegister({
47 | variables: {
48 | objects: [
49 | {
50 | id: data.user.id,
51 | name: name,
52 | email: emailId,
53 | companyName: companyName,
54 | mobileNo: mobileNo,
55 | },
56 | ],
57 | },
58 | });
59 | alert("To verify email checkout your inbox..");
60 | navigate("/login");
61 | }
62 |
63 | setName("");
64 | setPassword("");
65 | setCompanyName("");
66 | setEmailId("");
67 | setMobileNo("");
68 | };
69 |
70 | return (
71 |
72 |
73 |
74 | Register as a recruiter
75 |
76 |
181 |
182 |
183 | );
184 | };
185 |
186 | export default RegisterHR;
187 |
--------------------------------------------------------------------------------
/src/Screens/HR/CreateRound.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useParams } from "react-router";
3 | import { useNavigate } from "react-router-dom";
4 | import { supabase } from "../../Utils/supabase.config";
5 | import { CREATE_NEW_ROUND } from "../../Graphql/Mutations/recruter";
6 | import { useMutation, useQuery } from "@apollo/client";
7 | import { GET_RECRUITER_INFO } from "../../Graphql/Queries/recruiter";
8 | import { useDispatch, useSelector } from "react-redux";
9 | import {
10 | addNewRound,
11 | getAllRoundsDetails,
12 | } from "../../actions/interviewRoundActions";
13 |
14 | const CreateRound = () => {
15 | const { jobId } = useParams();
16 | const navigate = useNavigate();
17 | const dispatch = useDispatch();
18 |
19 | const [round, setRound] = useState(0);
20 | const [isFinal, setIsFinal] = useState(false);
21 | const [roundDetails, setRoundDetails] = useState("");
22 | const [dateDeadline, setDateDeadline] = useState("");
23 | const [recruterId, setRecruterId] = useState();
24 | const [recruterCompanyName, setrecruterCompanyName] = useState("");
25 |
26 | const [createNewRound, { data: roundData }] = useMutation(CREATE_NEW_ROUND);
27 |
28 | const {
29 | loading,
30 | error,
31 | data: recruiterInfo,
32 | } = useQuery(GET_RECRUITER_INFO, {
33 | variables: { _eq: recruterId },
34 | onCompleted: (data) => {
35 | console.log(data, "DATaaaaa");
36 | setRecruterId(data?.Recruiters[0]?.id);
37 | setrecruterCompanyName(data?.Recruiters[0]?.companyName);
38 | },
39 | });
40 |
41 | useEffect(() => {
42 | const role = "";
43 | supabase.auth.getSession().then((res) => {
44 | if (res?.data?.session?.user) {
45 | console.log(" HR ", res?.data?.session?.user.id);
46 | setRecruterId(res?.data?.session?.user?.id);
47 | } else navigate("/login");
48 | let role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
49 | console.log(role);
50 | if (role && role != "hr") navigate(`/${role}`);
51 | });
52 | }, []);
53 |
54 | const handleSubmit = async (e) => {
55 | e.preventDefault();
56 | if (!(dateDeadline && roundDetails)) return alert("All fields required");
57 |
58 |
59 | // createNewRound({
60 | // variables: {
61 | // object: {
62 | // roundNo: round,
63 | // isFinal: isFinal,
64 | // roundTime: dateDeadline,
65 | // roundDetail: roundDetails,
66 | // jobId: jobId,
67 | // status: "upcomming",
68 | // companyName: recruterCompanyName,
69 | // shortlistStudentList: {
70 | // list: [],
71 | // },
72 | // },
73 | // },
74 | // });
75 |
76 | dispatch(
77 | addNewRound({
78 | roundNo: round,
79 | isFinal: isFinal,
80 | roundTime: dateDeadline,
81 | roundDetail: roundDetails,
82 | jobId: jobId,
83 | status: "upcomming",
84 | companyName: recruterCompanyName,
85 | shortlistStudentList: {
86 | list: [],
87 | },
88 | })
89 | );
90 |
91 | alert("round created");
92 |
93 | navigate(`/hr/createdjobs/${jobId}/`);
94 | };
95 |
96 | return (
97 |
98 |
99 |
Create Round
100 |
194 |
195 |
196 | );
197 | };
198 |
199 | export default CreateRound;
200 |
--------------------------------------------------------------------------------
/src/Screens/Admin/RegisterAdmin/RegisterAdmin.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { supabase } from "../../../Utils/supabase.config";
4 | import { CREATE_NEW_ADMIN_MUTATION } from "../../../Graphql/Mutations/admin";
5 | import { useMutation } from '@apollo/client';
6 |
7 | const customStyles = {
8 | content: {
9 | top: "50%",
10 | left: "60%",
11 | right: "auto",
12 | bottom: "auto",
13 | width: "45%",
14 | display: "flex",
15 | flexDirection: "column",
16 | marginRight: "-50%",
17 | transform: "translate(-50%, -50%)",
18 | },
19 | };
20 |
21 | const RegisterAdmin = () => {
22 | const [userInfo, setUserInfo] = useState();
23 | const navigate = useNavigate();
24 | useEffect(() => {
25 | supabase.auth.getSession().then((res) => {
26 | // console.log(res);
27 | const role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
28 | if (role) navigate(`/${role}`);
29 | setUserInfo(res?.data?.session?.user);
30 | });
31 |
32 | // console.log(userInfo);
33 | }, []);
34 |
35 | const [firstName, setfirstName] = useState("");
36 | const [middleName, setMiddleName] = useState("");
37 | const [lastName, setLastName] = useState("");
38 | const [emailId, setEmailId] = useState("");
39 | const [gender, setGender] = useState("");
40 | const [dob, setDOB] = useState("");
41 | const [password, setPassword] = useState("");
42 |
43 | const [adminRegister, { adminData, adminLoading, adminError }] = useMutation(CREATE_NEW_ADMIN_MUTATION);
44 |
45 | const handleSubmit = async (e) => {
46 | // const { error } = await supabase.auth.signOut();
47 | if (!(firstName && middleName && lastName && emailId && gender && dob && password))
48 | return alert("All fields required");
49 |
50 | e.preventDefault();
51 | console.log(
52 |
53 | firstName,
54 | middleName,
55 | lastName,
56 | emailId,
57 | gender,
58 | dob,
59 | password
60 | );
61 |
62 | const { data, error } = await supabase.auth.signUp({
63 | email: emailId,
64 | password: password,
65 | options: {
66 | data: {
67 | role: "admin",
68 | },
69 | },
70 | });
71 | // console.log(data,"data")
72 |
73 | if (!error) {
74 | setUserInfo(data?.session);
75 | adminRegister({
76 | variables: {
77 | objects: [
78 | {
79 | "id": data.user.id,
80 | "firstName": firstName,
81 | "lastName": lastName,
82 | "middleName": middleName,
83 | "gender": gender,
84 | "clgEmail": emailId
85 | }
86 | ]
87 | }
88 | })
89 | console.log(adminData, adminError,adminLoading, "after gql query")
90 |
91 | navigate("/login");
92 | } else alert(error?.message);
93 | };
94 |
95 | return (
96 |
98 |
99 |
100 | Register as a admin
101 |
102 |
253 |
254 |
255 | );
256 | };
257 |
258 | export default RegisterAdmin;
259 |
--------------------------------------------------------------------------------
/src/Screens/HR/ApplicantList.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { Link, useNavigate } from "react-router-dom";
3 | import { useParams } from "react-router";
4 | import { useQuery, useMutation } from "@apollo/client";
5 | import { GET_ALL_STUDENTS } from "../../Graphql/Queries/AdminViewStudents/adminViewStudents";
6 | import {
7 | GET_APPLICANT_LIST_BY_JOB_ID_QUERY,
8 | GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY,
9 | } from "../../Graphql/Queries/recruiter";
10 | import { STUDENT_TRANSITION_FOR_NEXT_ROUND } from "../../Graphql/Mutations/recruter";
11 |
12 | const ApplicantList = () => {
13 | const { jobId, roundId } = useParams();
14 | const navigate = useNavigate();
15 |
16 | const [applications, setApplications] = useState([]);
17 | const [rounds, setRounds] = useState([]);
18 | const [shortlistedStudents, setShortlistedStudents] = useState([]);
19 |
20 | const { loading, error } = useQuery(GET_APPLICANT_LIST_BY_JOB_ID_QUERY, {
21 | onCompleted: (data) => {
22 | setApplications(data.Applications);
23 | },
24 | variables: {
25 | jobId: jobId,
26 | },
27 | });
28 |
29 | const { error: eError } = useQuery(GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY, {
30 | onCompleted: (data) => setRounds(data.Rounds),
31 | variables: {
32 | applicationId: jobId,
33 | },
34 | });
35 |
36 | const [studentTransition, { data: d, error: sError }] = useMutation(
37 | STUDENT_TRANSITION_FOR_NEXT_ROUND
38 | );
39 |
40 | const checkHandler = (id) => {
41 | setShortlistedStudents(
42 | shortlistedStudents.includes(id)
43 | ? shortlistedStudents.filter((item) => item != id)
44 | : [...shortlistedStudents, id]
45 | );
46 | // console.log(shortlistedStudents, " heyyyy");
47 | };
48 |
49 | const handleShortlist = () => {
50 | if (shortlistedStudents?.length === 0) return;
51 | else if (rounds?.length === 0) {
52 | alert("Create Round First");
53 | return;
54 | }
55 |
56 | const variables = {
57 | roundId: rounds?.[0]?.id,
58 | _set: {
59 | shortlistStudentList: {
60 | list: shortlistedStudents,
61 | },
62 | },
63 | };
64 |
65 | studentTransition({
66 | variables,
67 | });
68 |
69 | alert(`${shortlistedStudents.length} students shortlisted for next round`);
70 | navigate(`/hr/createdjobs/${jobId}/${rounds[0]?.id}`);
71 | };
72 |
73 | if (loading)
74 | return (
75 |
83 | );
84 | return (
85 | <>
86 |
87 | Applicant List
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
101 | Sr.No
102 |
103 |
107 | is ShortList
108 |
109 |
113 | ID
114 |
115 |
119 | Name
120 |
121 |
125 | Branch
126 |
127 |
131 | CPI
132 |
133 |
137 | Email
138 |
139 |
143 | Resume Link
144 |
145 |
149 | Gender
150 |
151 |
152 |
153 |
154 | {applications.length == 0 ? (
155 |
156 | No Record Found
157 |
158 | ) : (
159 | <>
160 | {applications.map((row, index) => {
161 | const { id: applicationId, resumeLink, Student } = row;
162 | const {
163 | id: studentId,
164 | CPI,
165 | branch,
166 | clgEmail,
167 | gender,
168 | firstName,
169 | lastName,
170 | mobileNumber,
171 | clgId,
172 | } = Student;
173 |
174 | const fullName =
175 | (firstName?.length ? firstName : " ") +
176 | (lastName?.length ? lastName : "");
177 |
178 | return (
179 |
180 |
181 | {index + 1}
182 |
183 |
184 |
185 | checkHandler(applicationId)}
192 | id="flexCheckDefault"
193 | />
194 |
195 |
196 |
197 | {clgId}
198 |
199 |
200 | {fullName?.length ? fullName : "NA"}
201 |
202 |
203 | {branch?.length ? branch : "NA"}
204 |
205 |
206 | {CPI}
207 |
208 |
209 |
215 | send mail
216 |
217 |
218 |
219 |
224 | Resume
225 |
226 |
227 |
228 | {gender ? gender : "NA"}
229 |
230 |
231 | );
232 | })}
233 | >
234 | )}
235 |
236 |
237 | {shortlistedStudents?.length ? (
238 |
239 |
240 |
250 | ShortList Students
251 |
252 |
253 |
254 | ) : (
255 | ""
256 | )}
257 |
258 |
259 |
260 |
261 | >
262 | );
263 | };
264 |
265 | export default ApplicantList;
266 |
--------------------------------------------------------------------------------
/src/Screens/HR/RoundDetail.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useParams, useNavigate } from "react-router";
3 | import { GET_ALL_STUDENTS } from "../../Graphql/Queries/AdminViewStudents/adminViewStudents";
4 | import { useQuery, useMutation } from "@apollo/client";
5 | import {
6 | GET_ALL_DETAILS_OF_ONE_ROUND_QUERY,
7 | GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY,
8 | GET_STUDENTS_DETAILS_FRO_EACH_ROUND_QUERY,
9 | } from "../../Graphql/Queries/recruiter";
10 | import {
11 | STUDENT_TRANSITION_FOR_NEXT_ROUND,
12 | MARK_FINAL_REJECT_STUDENTS_MUTATION,
13 | MARK_FINAL_SELECT_STUDENTS_MUTATION,
14 | } from "../../Graphql/Mutations/recruter";
15 |
16 | const RoundDetails = () => {
17 | const { jobId, roundId } = useParams();
18 | const navigate = useNavigate();
19 |
20 | const [rounds, setRounds] = useState([]);
21 | const [roundInfo, setRoundInfo] = useState({});
22 | const [studentsInfo, setStudentsInfo] = useState([]);
23 | const [shortlistedStudents, setShortlistedStudents] = useState([]);
24 |
25 | useEffect(() => {
26 | setShortlistedStudents([]);
27 | }, []);
28 |
29 | const { error: eError } = useQuery(GET_ROUNDS_INFO_BY_APPLICATIONID_QUERY, {
30 | onCompleted: (data) => {
31 | setRounds(data.Rounds);
32 | },
33 | variables: {
34 | applicationId: jobId,
35 | },
36 | });
37 |
38 | const {
39 | loading: roundInfoLoading,
40 | error: roundInfoError,
41 | refetch: refetchRoundDetails,
42 | } = useQuery(GET_ALL_DETAILS_OF_ONE_ROUND_QUERY, {
43 | onCompleted: (data) => {
44 | setRoundInfo(data.Rounds_by_pk);
45 | let currentRoundNumber = 0;
46 | rounds?.forEach((row, index) => {
47 | if (row?.id == roundId) currentRoundNumber = index;
48 | });
49 |
50 | if (currentRoundNumber + 1 < rounds.length) {
51 | setShortlistedStudents(
52 | rounds[currentRoundNumber + 1]?.shortlistStudentList?.list
53 | );
54 | }
55 | },
56 | variables: {
57 | roundId: roundId,
58 | },
59 | });
60 |
61 | const {
62 | loading: studentsInfoLoading,
63 | error: studentsInfoError,
64 | refetch: refetchStudentsInfo,
65 | } = useQuery(GET_STUDENTS_DETAILS_FRO_EACH_ROUND_QUERY, {
66 | onCompleted: (data) => setStudentsInfo(data.Applications),
67 | variables: {
68 | jobId,
69 | applicationIds: roundInfo?.shortlistStudentList?.list ?? [],
70 | },
71 | });
72 |
73 | const [studentTransition, { data }] = useMutation(
74 | STUDENT_TRANSITION_FOR_NEXT_ROUND
75 | );
76 |
77 | const [selectFinalStudents, { data: finalStudentsData }] = useMutation(
78 | MARK_FINAL_SELECT_STUDENTS_MUTATION
79 | );
80 | const [rejectFinalStudents, { data: finalStudentsDataRejects }] = useMutation(
81 | MARK_FINAL_REJECT_STUDENTS_MUTATION
82 | );
83 |
84 | //helper fucntions
85 | const checkHandler = (id) => {
86 | setShortlistedStudents(
87 | shortlistedStudents.includes(id)
88 | ? shortlistedStudents.filter((item) => item != id)
89 | : [...shortlistedStudents, id]
90 | );
91 | // console.log(shortlistedStudents, " heyyyy");
92 | };
93 | const handleShortlist = () => {
94 | // console.log(shortlistedStudents, " heyyyy");
95 | let currentRoundNumber = 0;
96 | rounds?.forEach((row, index) => {
97 | if (row?.id == roundId) currentRoundNumber = index;
98 | });
99 | // console.log(rounds);
100 | if (!(currentRoundNumber + 1 < rounds.length)) {
101 | return alert("Create Next Round First & then only shortlist");
102 | }
103 | const nextRoundId = rounds[currentRoundNumber + 1]?.id;
104 | const variables = {
105 | roundId: nextRoundId,
106 | _set: {
107 | shortlistStudentList: {
108 | list: shortlistedStudents,
109 | },
110 | },
111 | };
112 |
113 | studentTransition({ variables });
114 | alert(`${shortlistedStudents?.length} students forwarded to next round...`);
115 | setShortlistedStudents([]);
116 | navigate(`/hr/createdjobs/${jobId}/${nextRoundId}`);
117 | };
118 |
119 | const finalSelects = () => {
120 | rejectFinalStudents({
121 | variables: {
122 | jobId,
123 | },
124 | });
125 |
126 | selectFinalStudents({
127 | variables: {
128 | applicationsIds: shortlistedStudents,
129 | roundId,
130 | },
131 | });
132 |
133 | if (finalStudentsData?.update_Applications_many?.affected_rows || true) {
134 | alert(`${shortlistedStudents?.length} students marked as Selected!!!`);
135 | }
136 | };
137 |
138 | if (roundInfoLoading)
139 | return (
140 |
141 |
145 | .
146 |
147 |
148 | );
149 |
150 | return (
151 | <>
152 |
153 | Round No : {roundInfo?.roundNo ?? "-"}
154 |
155 | {/* reftech button here */}
156 |
157 |
158 |
159 | {
163 | refetchRoundDetails({ roundId });
164 |
165 | setTimeout(() => {
166 | refetchStudentsInfo({
167 | jobId,
168 | applicationIds: roundInfo?.shortlistStudentList?.list ?? [],
169 | });
170 | }, 100);
171 |
172 | setShortlistedStudents([]);
173 | }}
174 | >
175 | Refresh List
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
191 | Sr.No
192 |
193 |
197 | is ShortList
198 |
199 |
203 | ID
204 |
205 |
209 | Name
210 |
211 |
215 | Branch
216 |
217 |
221 | CPI
222 |
223 |
227 | Send Mail
228 |
229 |
233 | Resume Link
234 |
235 |
239 | Gender
240 |
241 |
242 |
243 |
244 | {studentsInfo.length == 0 ? (
245 |
246 | No Record Found
247 |
248 | ) : (
249 | <>
250 | {studentsInfo.map((row, index) => {
251 | const {
252 | id: applicationId,
253 | resumeLink,
254 | selectionStatus,
255 | Student,
256 | } = row;
257 | const {
258 | id: studentId,
259 | CPI,
260 | branch,
261 | clgEmail,
262 | gender,
263 | firstName,
264 | lastName,
265 | mobileNumber,
266 | clgId,
267 | programme,
268 | gradYear,
269 | } = Student;
270 |
271 | const fullName =
272 | (firstName?.length ? firstName : " ") +
273 | (lastName?.length ? lastName : "");
274 |
275 | return (
276 |
277 |
278 | {index + 1}
279 |
280 |
281 |
282 | checkHandler(applicationId)}
289 | id="flexCheckDefault"
290 | />
291 | {selectionStatus === 1 && (
292 |
293 | Selected
294 |
295 | )}
296 |
297 |
298 |
299 | {clgId}
300 |
301 |
302 | {fullName?.length ? fullName : "NA"}
303 |
304 |
305 | {branch?.length ? branch : "NA"}
306 |
307 |
308 | {CPI}
309 |
310 |
311 |
317 | send mail
318 |
319 |
320 |
321 |
326 | Resume
327 |
328 |
329 |
330 |
331 | {gender ? gender : "NA"}
332 |
333 |
334 | );
335 | })}
336 | >
337 | )}
338 |
339 |
340 | {shortlistedStudents?.length ? (
341 |
342 |
343 | {
354 | if (roundInfo?.isFinal) finalSelects();
355 | else handleShortlist();
356 | }}
357 | >
358 | {roundInfo?.isFinal
359 | ? "Final Selects"
360 | : "ShortList for next round"}
361 |
362 |
363 |
364 | ) : (
365 | ""
366 | )}
367 |
368 |
369 |
370 |
371 | >
372 | );
373 | };
374 |
375 | export default RoundDetails;
376 |
--------------------------------------------------------------------------------
/src/Screens/Admin/ViewStudents/ViewStudents.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import {
3 | Container,
4 | Button,
5 | Table,
6 | TableBody,
7 | TableCell,
8 | TableContainer,
9 | TableHead,
10 | TableRow,
11 | Paper,
12 | Checkbox,
13 | Box,
14 | CircularProgress,
15 | } from "@mui/material";
16 | import styles from "../TpoPolicy/TpoPolicy.module.css";
17 | // import StudentsTable from "../../../Components/AdminViewStudents/StudentsTable";
18 | import { GET_ALL_STUDENTS } from "../../../Graphql/Queries/AdminViewStudents/adminViewStudents";
19 | import { useQuery, useMutation } from "@apollo/client";
20 | import ASidebar from "../../../Components/adminSidebar/ASidebar";
21 | import CriteriaDropdown from "../../../Components/AdminViewStudents/CriteriaDropdown";
22 | import { UPDATE_STUDENT_FOR_CR_MUTATION } from "../../../Graphql/Mutations/admin";
23 |
24 | const CHOOSE_ALL_VAL_INT = 0;
25 | const CHOOSE_ALL_VAL_STR = " ";
26 | const CHOOSE_ALL_VAL_OBJ = { name: CHOOSE_ALL_VAL_STR };
27 | const CHOOSE_ALL_NAME = "All";
28 | const PLACED_NP = "Not placed";
29 | const PLACED_N = "Normal";
30 | const PLACED_D = "Dream";
31 | const PLACED_SD = "Super Dream";
32 | const PLACED_CHOICES = [PLACED_NP, PLACED_N, PLACED_D, PLACED_SD];
33 |
34 | const cpiRange = (max, min) => {
35 | return {
36 | max: max,
37 | min: min,
38 | name: max.toString() + " - " + min.toString(),
39 | };
40 | };
41 |
42 | const CPI_RANGES = [
43 | cpiRange(10, 9.5),
44 | cpiRange(9.5, 9),
45 | cpiRange(9, 8.5),
46 | cpiRange(8.5, 8),
47 | cpiRange(8, 7.5),
48 | cpiRange(7.5, 7),
49 | cpiRange(7, 6.5),
50 | cpiRange(6.5, 6),
51 | cpiRange(6, 5.5),
52 | cpiRange(5.5, 5),
53 | cpiRange(5, 4.5),
54 | cpiRange(4.5, 4),
55 | cpiRange(4, 3.5),
56 | cpiRange(3.5, 3),
57 | cpiRange(3, 2.5),
58 | cpiRange(2.5, 2),
59 | cpiRange(2, 1.5),
60 | cpiRange(1.5, 1),
61 | cpiRange(1, 0.5),
62 | cpiRange(0.5, 0),
63 | ];
64 |
65 | const cpiRangeObjFromName = (cpiRangeName) => {
66 | if (cpiRangeName === CHOOSE_ALL_VAL_STR) {
67 | return CHOOSE_ALL_VAL_OBJ;
68 | }
69 | const cpiRangeParts = cpiRangeName.split(" - ");
70 | const cpiRangeMax = Number(cpiRangeParts[0]);
71 | const cpiRangeMin = Number(cpiRangeParts[1]);
72 | return cpiRange(cpiRangeMax, cpiRangeMin);
73 | };
74 |
75 | const studentFilter = (
76 | student,
77 | chosenProgram,
78 | chosenBranch,
79 | chosenGradYear,
80 | chosenPlaced,
81 | chosenCpiRange
82 | ) => {
83 | return (
84 | (chosenProgram === CHOOSE_ALL_VAL_STR ||
85 | chosenProgram === student.programme) &&
86 | (chosenBranch === CHOOSE_ALL_VAL_STR || chosenBranch === student.branch) &&
87 | (chosenGradYear === 0 || chosenGradYear === student.gradYear) &&
88 | (chosenPlaced === CHOOSE_ALL_VAL_STR ||
89 | (chosenPlaced === PLACED_SD && student.isSuperPlaced) ||
90 | (chosenPlaced === PLACED_D && student.isDreamPlaced) ||
91 | (chosenPlaced === PLACED_N && student.isNormalPlaced) ||
92 | (chosenPlaced === PLACED_NP &&
93 | !(
94 | student.isNormalPlaced ||
95 | student.isDreamPlaced ||
96 | student.isSuperPlaced
97 | ))) &&
98 | (chosenCpiRange.name === CHOOSE_ALL_VAL_STR ||
99 | (chosenCpiRange.max >= student.CPI && student.CPI >= chosenCpiRange.min))
100 | );
101 | };
102 |
103 | // function createStudentData(
104 | // name,
105 | // branch,
106 | // id,
107 | // year,
108 | // gender,
109 | // isCR
110 | // ) {
111 | // return { name, branch, id, year, gender, isCR };
112 | // }
113 |
114 | // var dashboardData= {
115 | // "overview":[
116 | // {"desc":"Total companies",
117 | // "value":300,
118 | // "color_val": "#8cf0f5"},
119 | // {"desc":"Total students registered",
120 | // "value": 4000,
121 | // "color_val": "#5fd986"}
122 | // ],
123 | // "students":{
124 | // "placements":[
125 | // {"desc":"Students registered",
126 | // "value": 2000,
127 | // "color_val": "#9d83f2"},
128 | // {"desc":"Students placed",
129 | // "value": 1800,
130 | // "color_val": "#f5a262"},
131 | // {"desc":"Highest CTC",
132 | // "value": "50 LPA",
133 | // "color_val": "#e0f57a"}
134 | // ],
135 | // "internships":[
136 | // {"desc":"Students registered",
137 | // "value":2000,
138 | // "color_val": "#5f65d4"},
139 | // {"desc":"Students placed",
140 | // "value": 1900,
141 | // "color_val": "#96d4a3"},
142 | // {"desc":"Highest stipend (per month)",
143 | // "value": "3 Lac",
144 | // "color_val": "#f7adea"}
145 | // ]
146 | // },
147 | // "studentData": [
148 | // createStudentData('Abc', 'IT', 195235235, 4, "F", true),
149 | // createStudentData('Def', 'COMP', 204789330, 3, "F", false),
150 | // createStudentData('Ghi', 'COMP', 196378953, 2, "M", true),
151 | // createStudentData('Jkl', 'EXTC', 195364782, 1, "M", false),
152 | // ]
153 | // }
154 |
155 | // const data1 = {
156 | // Students: [
157 | // {
158 | // __typename: "Students",
159 | // CPI: 9.12,
160 | // SPI1: 0,
161 | // SPI2: 0,
162 | // SPI3: 0,
163 | // SPI4: 0,
164 | // SPI5: 0,
165 | // SPI6: 0,
166 | // SPI7: 0,
167 | // SPI8: 0,
168 | // age: 20,
169 | // branch: "CS",
170 | // clgEmail: "prrohokale_b19@ce.vjti.ac.in",
171 | // clgId: 191070000,
172 | // column_10th: 90,
173 | // column_12th: 90,
174 | // created_at: "2023-01-12T07:54:45.59504+00:00",
175 | // dob: "2002-09-29",
176 | // firstName: "Pranit",
177 | // gender: "Male",
178 | // gradYear: 2023,
179 | // id: "0173a65e-ac39-405c-8a92-e2fa1d6d49cb",
180 | // isCr: false,
181 | // isDreamPlaced: null,
182 | // isNormalPlaced: null,
183 | // isSuperPlaced: null,
184 | // lastName: "Rohokale",
185 | // middleName: "Rangnath ",
186 | // mobileNumber: 8446122060,
187 | // programme: "BTech",
188 | // resumeLink:
189 | // "https://docs.google.com/document/d/1CNkznkHiSqI1zSHLY-NRZy0MgXhDHg-RDPe5EuJqwQk/edit",
190 | // },
191 | // ],
192 | // };
193 |
194 | const ViewStudents = () => {
195 | const [students, setStudents] = useState([]);
196 | const [availablePrograms, setAvailablePrograms] = useState([]);
197 | const [availableBranches, setAvailableBranches] = useState([]);
198 | const [availableGradYears, setAvailableGradYears] = useState([]);
199 | const [updateStudentForCr, { crData, loadingM, hrError }] = useMutation(
200 | UPDATE_STUDENT_FOR_CR_MUTATION
201 | );
202 | const { loading, error } = useQuery(GET_ALL_STUDENTS, {
203 | onCompleted: (data) => {
204 | // console.log(data);
205 | setStudents(data.Students);
206 | var uniquePrograms = availablePrograms;
207 | var uniqueBraches = availableBranches;
208 | var uniqueGradYears = availableGradYears;
209 | for (var student of data.Students) {
210 | if (!uniquePrograms.includes(student.programme)) {
211 | uniquePrograms.push(student.programme);
212 | }
213 | if (!uniqueBraches.includes(student.branch)) {
214 | uniqueBraches.push(student.branch);
215 | }
216 | if (!uniqueGradYears.includes(student.gradYear)) {
217 | uniqueGradYears.push(student.gradYear);
218 | }
219 | }
220 | setAvailablePrograms(uniquePrograms);
221 | setAvailableBranches(uniqueBraches);
222 | setAvailableGradYears(uniqueGradYears);
223 | },
224 | });
225 | const updateStudent = (id, studentAttributes) => {
226 | var index = students.findIndex((x) => x.id === id);
227 | if (index === -1) {
228 | // handle error
229 | console.log("error: index= -1");
230 | } else {
231 | // console.log("New student attr:", studentAttributes);
232 | var newStudents = [
233 | ...students.slice(0, index),
234 | Object.assign({}, students[index], studentAttributes),
235 | ...students.slice(index + 1),
236 | ];
237 | // console.log("New students:", newStudents);
238 | setStudents(newStudents);
239 | }
240 | };
241 | const [updatedCrs, setUpdatedCrs] = useState({});
242 | const [chosenProgram, setChosenProgram] = useState(CHOOSE_ALL_VAL_STR);
243 | const [chosenBranch, setChosenBranch] = useState(CHOOSE_ALL_VAL_STR);
244 | const [chosenGradYear, setChosenGradYear] = useState(0);
245 | const [chosenPlaced, setChosenPlaced] = useState(CHOOSE_ALL_VAL_STR);
246 | const [chosenCpiRange, setChosenCpiRange] = useState(CHOOSE_ALL_VAL_OBJ);
247 |
248 | const handleSave = () => {
249 | for (var crId in updatedCrs) {
250 | updateStudentForCr({
251 | variables: {
252 | id: crId,
253 | isCr: updatedCrs[crId],
254 | },
255 | });
256 | }
257 | setUpdatedCrs({});
258 | // window.location.reload();
259 | };
260 |
261 | return (
262 |
263 |
264 |
265 | Student List
266 | {/*
275 | Student List
276 | */}
277 |
278 |
Filter by:
279 |
setChosenProgram(e.target.value)}
286 | available={availablePrograms}
287 | />
288 | setChosenBranch(e.target.value)}
295 | available={availableBranches}
296 | />
297 | setChosenGradYear(e.target.value)}
304 | available={availableGradYears}
305 | />
306 | setChosenPlaced(e.target.value)}
313 | available={PLACED_CHOICES}
314 | />
315 | {
322 | setChosenCpiRange(cpiRangeObjFromName(e.target.value));
323 | }}
324 | available={CPI_RANGES.map((cpi_range) => cpi_range.name)}
325 | />
326 | {/* {
328 | console.log(students);
329 | console.log(
330 | "Chosen Branch: " +
331 | chosenBranch +
332 | ", Chosen Grad Year: " +
333 | chosenGradYear.toString()
334 | );
335 | }}
336 | variant="contained"
337 | color="success"
338 | sx={{ margin: 3 }}
339 | >
340 | Log
341 | */}
342 |
343 |
344 |
345 | {error ? (
346 | "Error"
347 | ) : loading ? (
348 |
349 |
350 |
351 | ) : (
352 |
353 |
357 |
358 |
359 |
360 | Student Name
361 |
362 |
363 | Is CR
364 |
365 | Is Placed
366 | Programme
367 | Branch
368 |
369 | ID
370 |
371 |
372 | Grad Year
373 |
374 |
375 | Gender
376 |
377 |
378 | Age
379 |
380 |
381 | CPI
382 |
383 |
384 | 10th
385 |
386 |
387 | 12th
388 |
389 |
390 | Mobile
391 |
392 |
393 | Resume Link
394 |
395 |
396 |
397 |
398 | {students
399 | .filter((s) =>
400 | studentFilter(
401 | s,
402 | chosenProgram,
403 | chosenBranch,
404 | chosenGradYear,
405 | chosenPlaced,
406 | chosenCpiRange
407 | )
408 | )
409 | .map((row, index) => (
410 |
414 |
415 | {row.firstName + " " + row.lastName}
416 |
417 |
418 | {
421 | var oldCrVal = row.isCr;
422 | var newStudentAttr = { isCr: !oldCrVal }; //...students[index],
423 | updateStudent(row.id, newStudentAttr);
424 | var updatedCrs_ = updatedCrs;
425 | updatedCrs_[row.id] = !oldCrVal;
426 | setUpdatedCrs(updatedCrs_);
427 | console.log(updatedCrs);
428 | }}
429 | color="success"
430 | />
431 |
432 |
433 | {row.isSuperPlaced
434 | ? "Yes, Super dream"
435 | : row.isDreamPlaced
436 | ? "Yes, Dream"
437 | : row.isNormalPlaced
438 | ? "Yes, Normal"
439 | : "No"}
440 |
441 |
442 | {row.programme ? row.programme : "N/A"}
443 |
444 | {row.branch ? row.branch : "N/A"}
445 |
446 | {row.clgId ? row.clgId : "N/A"}
447 |
448 |
449 | {row.gradYear ? row.gradYear : "N/A"}
450 |
451 | {row.gender ? row.gender : "N/A"}
452 |
453 | {row.age ? row.age : "N/A"}
454 |
455 |
456 | {row.CPI ? row.CPI : "N/A"}
457 |
458 |
459 | {row.column_10th ? row.column_10th : "N/A"}
460 |
461 |
462 | {row.column_12th ? row.column_12th : "N/A"}
463 |
464 |
465 | {row.mobileNumber ? row.mobileNumber : "N/A"}
466 |
467 |
468 | {row.resumeLink ? (
469 |
472 | ) : (
473 | "N/A"
474 | )}
475 |
476 |
477 | ))}
478 |
479 |
480 |
481 | )}
482 | {
484 | window.location.reload();
485 | }}
486 | variant="contained"
487 | color="warning"
488 | sx={{ marginTop: 3, marginLeft: 90 }}
489 | disabled={Object.keys(updatedCrs).length === 0}
490 | >
491 | Discard Changes
492 |
493 | {
495 | handleSave();
496 | }}
497 | variant="contained"
498 | color="success"
499 | sx={{ marginTop: 3, marginLeft: 5 }}
500 | disabled={Object.keys(updatedCrs).length === 0}
501 | >
502 | Save Changes
503 |
504 |
505 |
506 | );
507 | };
508 |
509 | export default ViewStudents;
510 |
--------------------------------------------------------------------------------
/src/Screens/HR/CreateJob/CreateJob.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { supabase } from "../../../Utils/supabase.config";
4 | import Sidebar from "../../../Components/hrSidebar/Sidebar";
5 | import { useMutation, useQuery } from "@apollo/client";
6 | import { CREATE_NEW_JOB_MUTATION } from "../../../Graphql/Mutations/recruter";
7 | import { GET_RECRUTER_INFO } from "../../../Graphql/Queries/recruter";
8 | import moment from "moment";
9 | import styles from "./CreateJob.module.css"
10 |
11 |
12 | const branches = [
13 | {
14 | name: "Electrical",
15 | },
16 | {
17 | name: "Civil",
18 | },
19 | {
20 | name: "Mechanical",
21 | },
22 | {
23 | name: "EXTC",
24 | },
25 | {
26 | name: "Electronics",
27 | },
28 | {
29 | name: "Textile",
30 | },
31 | {
32 | name: "Computer",
33 | },
34 | {
35 | name: "IT",
36 | },
37 | {
38 | name: "Mechanical",
39 | },
40 | ];
41 |
42 |
43 | const CreateJob = () => {
44 | const [title, setTitle] = useState("");
45 | const [desc, setDesc] = useState("");
46 | const [salary, setSalary] = useState(0);
47 | const [noOfRounds, setNoOfRounds] = useState(0);
48 | const [location, setLocation] = useState("");
49 | const [ssc, setSsc] = useState(0);
50 | const [hsc, setHsc] = useState(0);
51 | const [cpi, setCpi] = useState(0);
52 | const [allowedGender, setAllowedGender] = useState("");
53 | const [allowedProgramme, setAlloweProgramme] = useState("");
54 | const [addReq, setAddReq] = useState("");
55 | const [timeDeadline, setTimeDeadline] = useState("11:59");
56 | const [dateDeadline, setDateDeadline] = useState("");
57 | const [userInfo, setUserInfo] = useState("");
58 |
59 | const [createNewJob, { jobData, jobloading, jobError }] = useMutation(
60 | CREATE_NEW_JOB_MUTATION
61 | );
62 |
63 | const { data, loading, error } = useQuery(GET_RECRUTER_INFO, {
64 | variables: {
65 | _eq: userInfo,
66 | },
67 | });
68 |
69 | const navigate = useNavigate();
70 |
71 | useEffect(() => {
72 | const role = "";
73 | supabase.auth.getSession().then((res) => {
74 | if (res?.data?.session?.user)
75 | console.log(" HR ", res?.data?.session?.user);
76 | else navigate("/login");
77 |
78 | // console.log(res?.data?.session?.user?.id);
79 | setUserInfo(res?.data?.session?.user?.id);
80 | const role = res?.data?.session?.user?.user_metadata?.role?.toLowerCase();
81 | console.log(role);
82 | if (role && role != "hr") navigate(`/${role}`);
83 | });
84 | }, [userInfo]);
85 |
86 | console.log( data, "getinfo");
87 |
88 | const [checkedState, setCheckedState] = useState(
89 | new Array(branches.length).fill(false)
90 | );
91 |
92 | const handleOnChange = (position) => {
93 | const updatedCheckedState = checkedState.map((item, index) =>
94 | index === position ? !item : item
95 | );
96 | setCheckedState(updatedCheckedState);
97 | };
98 |
99 | const handleSubmit = async (e) => {
100 | e.preventDefault();
101 | // if (!(title && desc && salary && noOfRounds && location && dateDeadline))
102 | // return alert("All fields required");
103 |
104 | let branchArr = [];
105 | checkedState.forEach((item, index) => {
106 | if (item == true) {
107 | branchArr.push(branches[index].name);
108 | }
109 | });
110 | let genderArr = [];
111 | let programmeArr = [];
112 | if (allowedGender === "female") {
113 | genderArr.push("female");
114 | } else if (allowedGender === "male") {
115 | genderArr.push("male");
116 | } else {
117 | genderArr.push("female");
118 | genderArr.push("male");
119 | }
120 |
121 | if (allowedProgramme === "btech") {
122 | programmeArr.push("btech");
123 | } else if (allowedProgramme === "mtech") {
124 | programmeArr.push("mtech");
125 | } else {
126 | programmeArr.push("btech");
127 | programmeArr.push("mtech");
128 | }
129 | if (!isNaN(cpi)) {
130 | setCpi(parseFloat(cpi));
131 | } else {
132 | setCpi(0);
133 | }
134 | console.log(branchArr, genderArr, programmeArr);
135 | console.log(
136 | title,
137 | desc,
138 | salary,
139 | noOfRounds,
140 | location,
141 | ssc,
142 | hsc,
143 | cpi,
144 | allowedGender,
145 | allowedProgramme,
146 | addReq,
147 | timeDeadline,
148 | dateDeadline
149 | );
150 |
151 | const encodeString = (arr = []) => {
152 | arr = arr.map((e) => e.trim().toLowerCase());
153 |
154 | return arr.join(",");
155 | };
156 |
157 | const toTimestamp = (strDate) => {
158 | const dt = moment(strDate).unix();
159 | return dt;
160 | };
161 |
162 | const company = data?.Recruiters?.[0]?.companyName;
163 |
164 | const variables = {
165 | newJob: {
166 | title: title,
167 | description: desc,
168 | salary: salary,
169 | endDateToApply: dateDeadline,
170 | locations: location,
171 | recruterId: userInfo,
172 | companyName: company,
173 | noOfRounds: noOfRounds,
174 | Job_Requirements: {
175 | data: {
176 | cpi,
177 | column_10th: ssc,
178 | column_12th: hsc,
179 | allowedGenders: encodeString(genderArr),
180 | allowedBranches: encodeString(branchArr),
181 | allowedPrograms: encodeString(programmeArr),
182 | },
183 | },
184 | },
185 | };
186 |
187 | console.log("varvariables ", variables);
188 |
189 | createNewJob({ variables });
190 | alert("new Job is created!!");
191 |
192 | setTitle("");
193 | setDesc("");
194 | setSalary(0);
195 | setNoOfRounds(0);
196 | setLocation("");
197 | };
198 |
199 | return (
200 |
201 |
202 |
203 | {/*
204 |
Welcome {data?.Recruiters?.[0]?.name}!
205 | */}
206 |
207 |
Create a Job
208 |
502 |
503 |
504 |
505 | );
506 | };
507 |
508 | export default CreateJob;
509 |
--------------------------------------------------------------------------------