diff --git a/package.json b/package.json index df98ea8c..1654f953 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "formik-wizard-form": "^2.1.0", "framer-motion": "^10.16.4", "js-cookie": "^3.0.5", + "jsonwebtoken": "^9.0.2", "jwt-decode": "^4.0.0", "lucide-react": "^0.302.0", "material-icons": "^1.13.12", diff --git a/src/components/Calendar/CalenderComponent/EventDetails.tsx b/src/components/Calendar/CalenderComponent/EventDetails.tsx index 94269e01..150ec7d8 100644 --- a/src/components/Calendar/CalenderComponent/EventDetails.tsx +++ b/src/components/Calendar/CalenderComponent/EventDetails.tsx @@ -98,7 +98,7 @@ export default function EventDetails() { Visible to Recruiter : - + {visibilityStatus(checked)} diff --git a/src/components/Calendar/context/ContextWrapper.tsx b/src/components/Calendar/context/ContextWrapper.tsx index 72d4c336..338ecdb8 100644 --- a/src/components/Calendar/context/ContextWrapper.tsx +++ b/src/components/Calendar/context/ContextWrapper.tsx @@ -4,6 +4,9 @@ import GlobalContext from "./GlobalContext"; import { selectedDayEvent } from "./GlobalContext"; import { fetchEvents } from "@/helpers/api"; import toast from "react-hot-toast"; +import Cookies from "js-cookie"; +import jwt from "jsonwebtoken"; +import { fetchStudentEvents } from "@/helpers/student/api"; export const labelsClasses = new Map([ ["INTERVIEW", "green"], @@ -57,10 +60,36 @@ export default function ContextWrapper(props: any) { useEffect(() => { async function fetchAndSetEvents() { try { - const data = await fetchEvents(); + const accessToken = Cookies.get("accessToken"); + let user = null; + + if (accessToken) { + try { + const decoded = jwt.decode(accessToken); + user = decoded ? { role: decoded.role } : null; + } catch (error) { + console.error("JWT decoding error:", error); + } + } + + let data; + + switch (user.role) { + case "ADMIN": + data = await fetchEvents(); + break; + case "RECRUITER": + data = await fetchStudentEvents(); + break; + case "STUDENT": + data = await fetchStudentEvents(); + break; + } + dispatchCallEvents({ type: "fetch", payload: data }); } catch (error) { toast.error("Failed to fetch events:"); + console.log(error); } } fetchAndSetEvents(); diff --git a/src/helpers/api.ts b/src/helpers/api.ts index 536c7fb3..cd3bb73b 100644 --- a/src/helpers/api.ts +++ b/src/helpers/api.ts @@ -144,16 +144,19 @@ export const PasswordlessLogin = async (accessToken: string | undefined) => { export const fetchFaculties = async () => { return apiCall("/faculties"); }; -export const postFacultyApproval = async (salaryId: string, facultyIds:string[]) => { - const faculties = facultyIds.map(id => ({ facultyId: id })); +export const postFacultyApproval = async ( + salaryId: string, + facultyIds: string[], +) => { + const faculties = facultyIds.map((id) => ({ facultyId: id })); const requestBody: { facultyId: string }[] = faculties; -console.log(requestBody); + console.log(requestBody); return apiCall(`/faculty-approvals/${salaryId}`, { method: "POST", - body:requestBody, + body: requestBody, }); -} +}; export const fetchAllSeasons = async () => { return apiCall("/seasons"); @@ -270,24 +273,22 @@ export const fetchJobEvents = async (jobId: any) => { }; export const fetchApprovals = async (filter?: string) => { -return apiCall(`/faculty-approvals`, { - queryParam:{ - q:{ - filterBy:{ - salary:{ - id:{ - eq:[filter,filter] - } - } - } - } -}}) -} - - + return apiCall(`/faculty-approvals`, { + queryParam: { + q: { + filterBy: { + salary: { + id: { + eq: [filter, filter], + }, + }, + }, + }, + }, + }); +}; export const fetchSeasonData = async (year: any, registered: boolean) => { - return apiCall(`/registrations`, { queryParam: { q: { diff --git a/src/helpers/student/api.ts b/src/helpers/student/api.ts index 3051da4c..e1199a9c 100644 --- a/src/helpers/student/api.ts +++ b/src/helpers/student/api.ts @@ -13,10 +13,14 @@ export const GetJobs = async () => { return apiCall(`/student-view/jobs`, { next: { tags: ["AllJobs"] } }); }; export const GetEventsByJobId = async (jobId: string) => { - return apiCall(`/student-view/events/${jobId}`, { next: { tags: ["AllJobs"] } }); + return apiCall(`/student-view/events/${jobId}`, { + next: { tags: ["AllJobs"] }, + }); }; export const GetOpportuinites = async () => { - return apiCall(`/student-view/opportunities`, { next: { tags: ["AllJobs"] } }); + return apiCall(`/student-view/opportunities`, { + next: { tags: ["AllJobs"] }, + }); }; export const GetSalaryById = async (salaryId: string) => { return apiCall(`/student-view/salaries/${salaryId}`, { @@ -40,11 +44,16 @@ export const GetResumes = async () => { return apiCall("/student-view/resume", { next: { tags: ["Resumes"] } }); }; export const RegisterSeason = async (seasonId: string, registered: boolean) => { - if(!registered){ - return apiCall(`/student-view/registrations/${seasonId}`, { method:"PATCH", next: { tags: ["Registrations"] } }); - } - else{ - return apiCall(`/student-view/de-register/${seasonId}`, { method:"PATCH", next: { tags: ["Registrations"] } }); + if (!registered) { + return apiCall(`/student-view/registrations/${seasonId}`, { + method: "PATCH", + next: { tags: ["Registrations"] }, + }); + } else { + return apiCall(`/student-view/de-register/${seasonId}`, { + method: "PATCH", + next: { tags: ["Registrations"] }, + }); } }; @@ -96,3 +105,7 @@ export const deleteResume = async (filename: string) => { next: { tags: ["Resumes"] }, }); }; + +export const fetchStudentEvents = async () => { + return apiCall("/student-view/events"); +}; diff --git a/src/middleware.ts b/src/middleware.ts index dc363749..c633137c 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,5 +1,6 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; +import jwt from "jsonwebtoken"; const adminRoutes = [ "/admin/company", @@ -31,8 +32,17 @@ const recruiterRoutes = [ const facultyRoutes = ["/faculty", "/faculty/profile"]; export function middleware(request: NextRequest) { - const userCookie = request.cookies.get("user"); - const user = userCookie ? JSON.parse(userCookie.value) : null; + const accessToken = request.cookies.get("accessToken"); + let user = null; + + if (accessToken) { + try { + const decoded = jwt.decode(accessToken.value); + user = decoded ? { role: decoded.role } : null; + } catch (error) { + console.error("JWT decoding error:", error); + } + } if (request.nextUrl.pathname === "/" && !user) { return NextResponse.redirect(new URL("/login", request.url)); diff --git a/yarn.lock b/yarn.lock index 9599a904..2dfb74d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1852,6 +1852,11 @@ browserslist@^4.23.0: node-releases "^2.0.14" update-browserslist-db "^1.0.16" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + busboy@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -2243,6 +2248,13 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + electron-to-chromium@^1.4.796: version "1.4.816" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.816.tgz#3624649d1e7fde5cdbadf59d31a524245d8ee85f" @@ -3339,6 +3351,22 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" @@ -3349,6 +3377,23 @@ json5@^1.0.2: object.assign "^4.1.4" object.values "^1.1.6" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + jwt-decode@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" @@ -3408,11 +3453,46 @@ lodash-es@^4.17.21: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash@^4.16.6, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -4608,6 +4688,11 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" +safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" @@ -4739,7 +4824,16 @@ string-convert@^0.2.0: resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4811,7 +4905,14 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==