Skip to content

Commit

Permalink
Schedule interview page.
Browse files Browse the repository at this point in the history
Schedule interview
  • Loading branch information
Suraj1089 authored Jan 3, 2024
2 parents 616a12a + e9c946e commit d570314
Show file tree
Hide file tree
Showing 15 changed files with 1,408 additions and 1,463 deletions.
997 changes: 170 additions & 827 deletions client/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@material-ui/pickers": "^3.3.10",
"@popperjs/core": "^2.11.7",
"@react-oauth/google": "^0.9.0",
"@syncfusion/ej2-data": "^24.1.41",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^12.8.3",
Expand Down
2 changes: 2 additions & 0 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Reset from './components/Password/Reset'
import Homepage from './components/Homepage/Homepage';
import RoleSelect from './components/RoleSelect/RoleSelect';
import VideosdkMeeting from './components/VideosdkMeeting/VideosdkMeeting';
import Schedule from './components/Schedule/Schedule';
import SeeScheduledInterviews from './components/SeeScheduledInterviews/SeeScheduledInterviews';

function App() {
Expand All @@ -32,6 +33,7 @@ function App() {
<Route path="/forgot" element={<Forgot/>} />
<Route path="/reset/:token" element={<Reset/>} />
<Route path="/select" element={<RoleSelect/>} />
<Route path="/schedule" element={<Schedule/>} />
</Routes>
</SnackbarProvider>
</BrowserRouter>
Expand Down
6 changes: 5 additions & 1 deletion client/src/actions/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ export const DELETE_PROFILE = 'DELETE_PROFILE';
export const FETCH_PROFILES = 'FETCH_PROFILES';
export const FETCH_PROFILE = 'FETCH_PROFILE';
export const FETCH_PROFILE_BY_USER = 'FETCH_PROFILE_USER';
export const FETCH_PROFILES_BY_USER = 'FETCH_PROFILES_BY_USER';
export const FETCH_PROFILES_BY_USER = 'FETCH_PROFILES_BY_USER';

export const LIST_MEETINGS = 'LIST_MEETINGS';
export const GET_MEETING = 'GET_MEETING';
export const SCHEDULE_MEETING = 'SCHEDULE_MEETING';
29 changes: 28 additions & 1 deletion client/src/actions/interviews.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GET_INTERVIEWS, START_LOADING } from './constants';
import { GET_INTERVIEWS, START_LOADING, LIST_MEETINGS, GET_MEETING, SCHEDULE_MEETING } from './constants.js';
import * as api from '../api/index.js';

export const getInterviewsCandidate = (id) => async (dispatch) => {
Expand All @@ -23,3 +23,30 @@ export const getInterviewsHR = (id) => async (dispatch) => {
return error;
}
};

export const listMeetings = () => async (dispatch) => {
try {
const { data } = await api.listMeetings();
dispatch({ type: LIST_MEETINGS, payload: data });
} catch (error) {
console.log(error);
}
};

export const getMeeting = (id) => async (dispatch) => {
try {
const { data } = await api.getMeeting(id);
dispatch({ type: GET_MEETING, payload: data });
} catch (error) {
console.log(error.response);
}
};

export const scheduleMeeting = (meetingData) => async (dispatch) => {
try {
const { data } = await api.scheduleMeeting(meetingData);
dispatch({ type: SCHEDULE_MEETING, payload: data });
} catch (error) {
console.log(error);
}
};
9 changes: 7 additions & 2 deletions client/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ API.interceptors.request.use((req) => {
if(localStorage.getItem('profile')) {
req.headers.authorization = `Bearer ${JSON.parse(localStorage.getItem('profile')).token}`
}

// console.log(req);
return req
})

Expand Down Expand Up @@ -51,4 +51,9 @@ export const updateProfile = (id, updatedProfile) => API.patch(`/profiles`, upda
export const deleteProfile = (id) => API.delete(`/profiles/${id}`);

export const getInterviewsCandidate = (id) => API.get(`/interviews/candidate/${id}`);
export const getInterviewsHR = (id) => API.get(`/interviews/hr/${id}`);
export const getInterviewsHR = (id) => API.get(`/interviews/hr/${id}`);

export const listMeetings = () => API.get('/meetings');
export const getMeeting = (id) => API.get(`/meetings/${id}`);
// export const scheduleMeeting = (meetingData) => API.post('/schedule', meetingData);
export const scheduleMeeting = (formData) => API.post(`/interviews/schedule`, formData);
10 changes: 9 additions & 1 deletion client/src/components/NavBar/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";

function NavBar() {
function NavBar({ userRole }) {
const [nav, setNav] = useState(false);
const [isButtonDisabled, setIsButtonDisabled] = useState(false);
const [user, setUser] = useState(JSON.parse(localStorage.getItem("profile")));
Expand Down Expand Up @@ -77,6 +77,14 @@ function NavBar() {
>
Meetings
</button>

{/* {userRole === "hr" && ( */}
<button
onClick={() => navigate("/schedule")}
>
Schedule Interviews
</button>
{/* )} */}
</ul>
<button
className="navbar-btn"
Expand Down
184 changes: 184 additions & 0 deletions client/src/components/Schedule/Schedule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import React, { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import { decode } from "jsonwebtoken";
import { useEffect } from "react";
import styles from "./Schedule.module.css";
import { scheduleMeeting } from "../../actions/interviews";
import { useSnackbar } from 'react-simple-snackbar'
import { useDispatch } from 'react-redux'

let prevUserToken = null;

const Schedule = () => {
const navigate = useNavigate();
const user = JSON.parse(localStorage.getItem("profile"));
const [userRole, setUserRole] = useState("");
const [openSnackbar, closeSnackbar] = useSnackbar()
const dispatch = useDispatch()

useEffect(() => {
if (!user) {
console.log('navigating')
navigate("/login");
}
const checkUserRole = async () => {
try {
const decodedToken = decode(user.token);
if (decodedToken) {
const userRole = decodedToken.role;
setUserRole(userRole);
} else {
setUserRole("");
}
} catch (error) {
console.error("Error fetching user profile:", error);
setUserRole("");
}
};

if (user && user.token !== prevUserToken) {
checkUserRole();
}

prevUserToken = user.token;
}, [user]);

const [formData, setFormData] = useState({
title: "",
description: "",
startDate: "",
startTime: "",
endTime: "",
email: "",
status: "",
room: "",
});

const handleChange = (e) => {
const { name, value } = e.target;
const newValue = name === 'startDate' ? new Date(value) : value;
setFormData((prevData) => ({ ...prevData, [name]: value }));
};

const handleSubmit = async (e) => {
e.preventDefault();

try {
// Send a request to the server to schedule the interview
await dispatch(scheduleMeeting(formData));

// Interview scheduled successfully
openSnackbar("Interview scheduled successfully!");
navigate("/homepage");
} catch (error) {
console.error("Error scheduling interview:", error.message);
openSnackbar("Could not schedule interview");
}
};

return (
<div className={styles.auth_container}>
<div className={styles.auth_content}>
<div className={styles.auth_form_container}>
<h1 className={styles.heading}>Schedule Interview</h1>

<form onSubmit={handleSubmit} className={styles.auth_form}>
{userRole === "hr" && (
<input
type="text"
id="title"
name="title"
placeholder="Title"
value={formData.title}
onChange={handleChange}
className={styles.input_feild}
required
/>
)}
{userRole === "hr" && (
<input
type="text"
id="description"
name="description"
placeholder="Description"
value={formData.description}
onChange={handleChange}
className={styles.input_feild}
required
/>
)}
{userRole === "hr" && (
<input
type="date"
id="startDate"
name="startDate"
value={formData.startDate}
onChange={handleChange}
className={styles.input_field}
required
/>
)}

{userRole === "hr" && (
<input
type="time"
id="startTime"
name="startTime"
value={formData.startTime}
onChange={handleChange}
className={styles.input_field}
required
/>
)}

{userRole === "hr" && (
<input
type="time"
id="endTime"
name="endTime"
value={formData.endTime}
onChange={handleChange}
className={styles.input_field}
/>
)}
{/* User field (disabled or hidden based on your UI/UX decision) */}
{userRole === "hr" && (
<input
type="text"
id="email"
name="email"
placeholder="Candidate email"
value={formData.email}
onChange={handleChange}
className={styles.input_feild}
// required
// disabled
/>
)}
{userRole === "hr" && (
<select
id="status"
name="status"
value={formData.status}
onChange={handleChange}
className={styles.input_field}
required
>
<option value="Scheduled">Scheduled</option>
<option value="Cancelled">Cancelled</option>
<option value="Completed">Completed</option>
<option value="Live">Live</option>
<option value="Postponed">Postponed</option>
<option value="Rescheduled">Rescheduled</option>
</select>
)}
<button className={styles.submit_button}>Schedule</button>
<Link to={"/homepage"}><button className={styles.back_button}>Back</button></Link>
</form>
</div>
</div>
</div>
);
};

export default Schedule;
Loading

0 comments on commit d570314

Please sign in to comment.