diff --git a/.dockerignore b/.dockerignore index bc2259c8..803c7ba1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,7 @@ -.git/ -.gitignore -.next/ -.dockerignore -Dockerfile -node_modules/ +.git/ +.gitignore +.next/ +.dockerignore +Dockerfile +node_modules/ docker-compose.yml \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index bffb357a..ea782d70 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,3 @@ -{ - "extends": "next/core-web-vitals" -} +{ + "extends": "next/core-web-vitals" +} diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 8db1b523..b9f71982 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -1,19 +1,19 @@ -name: build-test - -on: - pull_request: - types: [opened, synchronize, reopened] - -jobs: - build-lint-test: - runs-on: ubuntu-latest - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: yarn - cache-dependency-path: "yarn.lock" - - run: yarn - - run: yarn build +name: build-test + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + build-lint-test: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: yarn + cache-dependency-path: "yarn.lock" + - run: yarn + - run: yarn build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7f0b4a07..5cbe734d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,64 +1,64 @@ -name: Publish Frontend Image - -on: - release: - types: - - published - workflow_dispatch: - -env: - DOCKER_REPO: lofowebteam/tpc_portal_frontend - -jobs: - push_to_registry: - name: Push Docker image to Docker Hub - runs-on: ubuntu-latest - steps: - - name: Check out the repo - uses: actions/checkout@v4 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build and push Docker image - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile - push: true - tags: ${{ env.DOCKER_REPO }}:${{ github.sha }},${{ env.DOCKER_REPO }}:latest - cache-from: type=registry,ref=${{ env.DOCKER_REPO }}:buildcache - cache-to: type=registry,ref=${{ env.DOCKER_REPO }}:buildcache,mode=max - - bump_tag: - name: Bump tag into docker-compose.yml - needs: push_to_registry - runs-on: ubuntu-latest - steps: - - name: Checkout charts - uses: actions/checkout@v4 - with: - repository: Web-Team-IITI-Gymkhana/tpc-pipeline-testing - ref: "main" - token: ${{ secrets.TPC_GITHUB_ACTION_ADMIN }} - path: base_dir - - - name: Changing Chart version - uses: mikefarah/yq@v4.34.1 - with: - cmd: yq -i '.services.frontend.image = "${{ env.DOCKER_REPO }}:${{ github.sha }}"' base_dir/docker-compose.yml - - - name: Commit updated docker compose - run: | - cd base_dir - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - git add docker-compose.yml - git commit -m "[CI] Bump frontend image tag to ${{ github.sha }}" - git push +name: Publish Frontend Image + +on: + release: + types: + - published + workflow_dispatch: + +env: + DOCKER_REPO: lofowebteam/tpc_portal_frontend + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ env.DOCKER_REPO }}:${{ github.sha }},${{ env.DOCKER_REPO }}:latest + cache-from: type=registry,ref=${{ env.DOCKER_REPO }}:buildcache + cache-to: type=registry,ref=${{ env.DOCKER_REPO }}:buildcache,mode=max + + bump_tag: + name: Bump tag into docker-compose.yml + needs: push_to_registry + runs-on: ubuntu-latest + steps: + - name: Checkout charts + uses: actions/checkout@v4 + with: + repository: Web-Team-IITI-Gymkhana/tpc-pipeline-testing + ref: "main" + token: ${{ secrets.TPC_GITHUB_ACTION_ADMIN }} + path: base_dir + + - name: Changing Chart version + uses: mikefarah/yq@v4.34.1 + with: + cmd: yq -i '.services.frontend.image = "${{ env.DOCKER_REPO }}:${{ github.sha }}"' base_dir/docker-compose.yml + + - name: Commit updated docker compose + run: | + cd base_dir + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + git add docker-compose.yml + git commit -m "[CI] Bump frontend image tag to ${{ github.sha }}" + git push diff --git a/.github/workflows/push-to-server.yml b/.github/workflows/push-to-server.yml index 681e1a84..f404e04f 100644 --- a/.github/workflows/push-to-server.yml +++ b/.github/workflows/push-to-server.yml @@ -1,25 +1,25 @@ -name: Push To Server - -on: - push: - branches: - - main - -jobs: - deploy: - runs-on: ubuntu-latest - name: deploy on remote - steps: - - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.DC_HOST }} - username: ${{ secrets.DC_USER }} - password: ${{ secrets.DC_PASS }} - script: | - cd ~/tpc_portal/tpc-frontend - git pull origin main - docker stop tpc_portal-frontend-1 - docker rm tpc_portal-frontend-1 - docker rmi tpc_portal-frontend || true - cd .. - docker compose up -d +name: Push To Server + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + name: deploy on remote + steps: + - uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.DC_HOST }} + username: ${{ secrets.DC_USER }} + password: ${{ secrets.DC_PASS }} + script: | + cd ~/tpc_portal/tpc-frontend + git pull origin main + docker stop tpc_portal-frontend-1 + docker rm tpc_portal-frontend-1 + docker rmi tpc_portal-frontend || true + cd .. + docker compose up -d diff --git a/.gitignore b/.gitignore index 85eceb72..5e8fac59 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,36 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts -.env +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts +.env diff --git a/.prettierignore b/.prettierignore index 1b8ac889..d606dbcf 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,3 @@ -# Ignore artifacts: -build -coverage +# Ignore artifacts: +build +coverage diff --git a/.prettierrc b/.prettierrc index 0967ef42..69a88e3b 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1 +1 @@ -{} +{} diff --git a/Dockerfile b/Dockerfile index 757503c3..c9645f4b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ -FROM node:alpine - -WORKDIR /usr/app - -COPY ./package.json ./ -COPY ./yarn.lock ./ - -RUN yarn install --frozen-lockfile - -COPY ./ ./ - -RUN yarn build - -USER node - +FROM node:alpine + +WORKDIR /usr/app + +COPY ./package.json ./ +COPY ./yarn.lock ./ + +RUN yarn install --frozen-lockfile + +COPY ./ ./ + +RUN yarn build + +USER node + CMD [ "yarn", "start" ] \ No newline at end of file diff --git a/README.md b/README.md index c4033664..73ea1f0e 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,36 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/components.json b/components.json index e4f02213..f6314a8e 100644 --- a/components.json +++ b/components.json @@ -1,17 +1,17 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": true, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/app/globals.css", - "baseColor": "gray", - "cssVariables": false, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils" - } -} +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/app/globals.css", + "baseColor": "gray", + "cssVariables": false, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} diff --git a/next.config.js b/next.config.js index 4c1569aa..30426c17 100644 --- a/next.config.js +++ b/next.config.js @@ -1,18 +1,18 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - env: { - NEXT_PUBLIC_BACKEND_URL: process.env.NEXT_PUBLIC_BACKEND_URL, - }, - reactStrictMode: false, - images: { - domains: ["localhost"], - }, - webpack: (config, { isServer }) => { - if (!isServer) { - config.resolve.fallback.fs = false; - } - return config; - }, -}; - -module.exports = nextConfig; +/** @type {import('next').NextConfig} */ +const nextConfig = { + env: { + NEXT_PUBLIC_BACKEND_URL: process.env.NEXT_PUBLIC_BACKEND_URL, + }, + reactStrictMode: false, + images: { + domains: ["localhost"], + }, + webpack: (config, { isServer }) => { + if (!isServer) { + config.resolve.fallback.fs = false; + } + return config; + }, +}; + +module.exports = nextConfig; diff --git a/package.json b/package.json index 1654f953..7131cc1b 100644 --- a/package.json +++ b/package.json @@ -1,93 +1,92 @@ -{ - "name": "my-app", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", - "@faker-js/faker": "^8.4.1", - "@mui/icons-material": "^5.15.20", - "@mui/material": "^5.15.20", - "@mui/x-date-pickers": "^7.6.2", - "@radix-ui/colors": "^3.0.0", - "@radix-ui/react-accordion": "^1.1.2", - "@radix-ui/react-checkbox": "^1.0.4", - "@radix-ui/react-dialog": "^1.0.5", - "@radix-ui/react-dropdown-menu": "^2.0.6", - "@radix-ui/react-hover-card": "^1.0.7", - "@radix-ui/react-icons": "^1.3.0", - "@radix-ui/react-label": "^2.0.2", - "@radix-ui/react-popover": "^1.0.7", - "@radix-ui/react-scroll-area": "^1.0.5", - "@radix-ui/react-select": "^2.0.0", - "@radix-ui/react-separator": "^1.0.3", - "@radix-ui/react-slot": "^1.0.2", - "@radix-ui/react-toast": "^1.1.5", - "@reduxjs/toolkit": "^2.0.1", - "@tanstack/react-table": "^8.11.2", - "@types/qs": "^6.9.14", - "antd": "^5.19.1", - "axios": "^1.6.3", - "class-variance-authority": "^0.7.0", - "clsx": "^2.0.0", - "cmdk": "^0.2.0", - "copy-to-clipboard": "^3.3.3", - "csv-parser": "^3.0.0", - "dayjs": "^1.11.10", - "embla-carousel-react": "^8.0.0-rc19", - "export-to-csv": "^1.3.0", - "formik": "^2.4.5", - "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", - "material-react-table": "^2.13.0", - "next": "^14.1.4", - "next-auth": "^4.23.2", - "papaparse": "^5.4.1", - "pdf-lib": "^1.17.1", - "prettier": "3.3.3", - "qs": "^6.12.0", - "react": "latest", - "react-chronos": "^1.0.5", - "react-cool-onclickoutside": "^1.7.0", - "react-dom": "latest", - "react-google-button": "^0.7.2", - "react-hot-toast": "^2.4.1", - "react-icons": "^4.12.0", - "react-modal": "^3.16.1", - "react-redux": "^9.0.4", - "react-responsive": "^10.0.0", - "react-select": "^5.8.0", - "react-table": "^7.8.0", - "styled-components": "^6.1.8", - "tailwind-merge": "^2.2.0", - "tailwindcss-animate": "^1.0.7", - "xlsx": "^0.18.5", - "yup": "^1.3.3" - }, - "devDependencies": { - "@tailwindcss/forms": "^0.5.7", - "@types/js-cookie": "^3.0.6", - "@types/node": "latest", - "@types/papaparse": "^5.3.10", - "@types/react": "latest", - "@types/react-dom": "latest", - "@types/react-modal": "^3.16.3", - "autoprefixer": "latest", - "eslint": "latest", - "eslint-config-next": "latest", - "postcss": "latest", - "tailwindcss": "latest", - "typescript": "latest" - } -} +{ + "name": "my-app", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", + "@faker-js/faker": "^8.4.1", + "@mui/icons-material": "^5.15.20", + "@mui/material": "^5.15.20", + "@mui/x-date-pickers": "^7.6.2", + "@radix-ui/colors": "^3.0.0", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-hover-card": "^1.0.7", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-popover": "^1.0.7", + "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-toast": "^1.1.5", + "@reduxjs/toolkit": "^2.0.1", + "@tanstack/react-table": "^8.11.2", + "@types/qs": "^6.9.14", + "antd": "^5.19.1", + "axios": "^1.6.3", + "class-variance-authority": "^0.7.0", + "clsx": "^2.0.0", + "cmdk": "^0.2.0", + "copy-to-clipboard": "^3.3.3", + "csv-parser": "^3.0.0", + "dayjs": "^1.11.10", + "embla-carousel-react": "^8.0.0-rc19", + "export-to-csv": "^1.3.0", + "formik": "^2.4.5", + "formik-wizard-form": "^2.1.0", + "framer-motion": "^10.16.4", + "js-cookie": "^3.0.5", + "jwt-decode": "^4.0.0", + "lucide-react": "^0.302.0", + "material-icons": "^1.13.12", + "material-react-table": "^2.13.0", + "next": "^14.1.4", + "next-auth": "^4.23.2", + "papaparse": "^5.4.1", + "pdf-lib": "^1.17.1", + "prettier": "3.3.3", + "qs": "^6.12.0", + "react": "latest", + "react-chronos": "^1.0.5", + "react-cool-onclickoutside": "^1.7.0", + "react-dom": "latest", + "react-google-button": "^0.7.2", + "react-hot-toast": "^2.4.1", + "react-icons": "^4.12.0", + "react-modal": "^3.16.1", + "react-redux": "^9.0.4", + "react-responsive": "^10.0.0", + "react-select": "^5.8.0", + "react-table": "^7.8.0", + "styled-components": "^6.1.8", + "tailwind-merge": "^2.2.0", + "tailwindcss-animate": "^1.0.7", + "xlsx": "^0.18.5", + "yup": "^1.3.3" + }, + "devDependencies": { + "@tailwindcss/forms": "^0.5.7", + "@types/js-cookie": "^3.0.6", + "@types/node": "latest", + "@types/papaparse": "^5.3.10", + "@types/react": "latest", + "@types/react-dom": "latest", + "@types/react-modal": "^3.16.3", + "autoprefixer": "latest", + "eslint": "latest", + "eslint-config-next": "latest", + "postcss": "latest", + "tailwindcss": "latest", + "typescript": "latest" + } +} diff --git a/postcss.config.js b/postcss.config.js index 12a703d9..a1b36d24 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/public/cross.svg b/public/cross.svg index 7cbbe0ed..35f68d9f 100644 --- a/public/cross.svg +++ b/public/cross.svg @@ -1,21 +1,21 @@ - - - - + + + + \ No newline at end of file diff --git a/public/google_icon.svg b/public/google_icon.svg index d949ddeb..8e75ebec 100644 --- a/public/google_icon.svg +++ b/public/google_icon.svg @@ -1,44 +1,44 @@ -
{children}
- - ); -}; - -export default LoginModalLayout; +import React from "react"; + +interface Props { + children: React.ReactNode; +} + +const LoginModalLayout = ({ children }: Props) => { + return ( + <> +
{children}
+ + ); +}; + +export default LoginModalLayout; diff --git a/src/app/(authroutes)/login/page.tsx b/src/app/(authroutes)/login/page.tsx index fe8cb959..cc7f1676 100644 --- a/src/app/(authroutes)/login/page.tsx +++ b/src/app/(authroutes)/login/page.tsx @@ -1,9 +1,9 @@ -//this will be used to create the login page. -import React from "react"; -import LoginForm from "@/components/loginForms/loginForm"; - -const LoginPage = async () => { - return ; -}; - -export default LoginPage; +//this will be used to create the login page. +import React from "react"; +import LoginForm from "@/components/loginForms/loginForm"; + +const LoginPage = async () => { + return ; +}; + +export default LoginPage; diff --git a/src/app/(authroutes)/passwordless/[token]/page.tsx b/src/app/(authroutes)/passwordless/[token]/page.tsx index 5a2b59ae..65c2b919 100644 --- a/src/app/(authroutes)/passwordless/[token]/page.tsx +++ b/src/app/(authroutes)/passwordless/[token]/page.tsx @@ -1,51 +1,51 @@ -"use client"; -import { PasswordlessLogin } from "@/helpers/api"; -import toast from "react-hot-toast"; -import React, { useEffect, useState } from "react"; -import { useRouter } from "next/navigation"; -import Cookies from "js-cookie"; -import { jwtDecode } from "jwt-decode"; -import Loader from "@/components/Loader/loader"; - -const LoginPage = ({ - params, -}: { - params: { - token: string; - }; -}) => { - const router = useRouter(); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const login = async () => { - try { - const res = await PasswordlessLogin(params.token); - Cookies.set("accessToken", res.body.accessToken, { expires: 365 }); - Cookies.set("user", JSON.stringify(jwtDecode(res.body.accessToken)), { - expires: 365, - }); - toast.success("Logged in successfully"); - router.push("/recruiter"); - } catch (error) { - toast.error("Some Error Occurred"); - } finally { - setLoading(false); - } - }; - - login(); - }); - - return ( - <> - {loading && ( -
- -
- )} - - ); -}; - -export default LoginPage; +"use client"; +import { PasswordlessLogin } from "@/helpers/api"; +import toast from "react-hot-toast"; +import React, { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import Cookies from "js-cookie"; +import { jwtDecode } from "jwt-decode"; +import Loader from "@/components/Loader/loader"; + +const LoginPage = ({ + params, +}: { + params: { + token: string; + }; +}) => { + const router = useRouter(); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const login = async () => { + try { + const res = await PasswordlessLogin(params.token); + Cookies.set("accessToken", res.body.accessToken, { expires: 365 }); + Cookies.set("user", JSON.stringify(jwtDecode(res.body.accessToken)), { + expires: 365, + }); + toast.success("Logged in successfully"); + router.push("/recruiter"); + } catch (error) { + toast.error("Some Error Occurred"); + } finally { + setLoading(false); + } + }; + + login(); + }); + + return ( + <> + {loading && ( +
+ +
+ )} + + ); +}; + +export default LoginPage; diff --git a/src/app/(authroutes)/recruiter/signup/page.tsx b/src/app/(authroutes)/recruiter/signup/page.tsx new file mode 100644 index 00000000..6dba447d --- /dev/null +++ b/src/app/(authroutes)/recruiter/signup/page.tsx @@ -0,0 +1,12 @@ +import RecruiterSignup from "@/components/loginForms/recruiterSignup"; +import React from "react"; + +const Signup = () => { + return ( + <> + + + ); +}; + +export default Signup; diff --git a/src/app/(routes)/JAF/page.tsx b/src/app/(routes)/JAF/page.tsx index 35a6f4c5..b77f88b3 100644 --- a/src/app/(routes)/JAF/page.tsx +++ b/src/app/(routes)/JAF/page.tsx @@ -1,13 +1,13 @@ -"use client"; -import React from "react"; -import JAF from "@/components/JAF/JAF"; - -const JAFPage = () => { - return ( - <> - - - ); -}; - -export default JAFPage; +"use client"; +import React from "react"; +import JAF from "@/components/JAF/JAF"; + +const JAFPage = () => { + return ( + <> + + + ); +}; + +export default JAFPage; diff --git a/src/app/(routes)/admin/JAF/layout.tsx b/src/app/(routes)/admin/JAF/layout.tsx index e678210d..48d4d77d 100644 --- a/src/app/(routes)/admin/JAF/layout.tsx +++ b/src/app/(routes)/admin/JAF/layout.tsx @@ -1,12 +1,12 @@ -import Loading from "@/components/common/loading"; -import { Suspense } from "react"; - -interface Props { - children: React.ReactNode; -} - -const JAFLayout = ({ children }: Props) => { - return }>{children}; -}; - -export default JAFLayout; +import Loading from "@/components/common/loading"; +import { Suspense } from "react"; + +interface Props { + children: React.ReactNode; +} + +const JAFLayout = ({ children }: Props) => { + return }>{children}; +}; + +export default JAFLayout; diff --git a/src/app/(routes)/admin/JAF/loading.tsx b/src/app/(routes)/admin/JAF/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/JAF/loading.tsx +++ b/src/app/(routes)/admin/JAF/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/JAF/page.tsx b/src/app/(routes)/admin/JAF/page.tsx index daa5297a..f0b3b219 100644 --- a/src/app/(routes)/admin/JAF/page.tsx +++ b/src/app/(routes)/admin/JAF/page.tsx @@ -1,8 +1,8 @@ -import React from "react"; -import JAF from "@/components/JAF/JAF"; - -function page() { - return ; -} - -export default page; +import React from "react"; +import JAF from "@/components/JAF/JAF"; + +function page() { + return ; +} + +export default page; diff --git a/src/app/(routes)/admin/companies/layout.tsx b/src/app/(routes)/admin/companies/layout.tsx index 14d4e80b..eb34d49e 100644 --- a/src/app/(routes)/admin/companies/layout.tsx +++ b/src/app/(routes)/admin/companies/layout.tsx @@ -1,14 +1,14 @@ -interface Props { - children: React.ReactNode; -} - -const CompanyLayout = ({ children }: Props) => { - return ( -
- {/* {allcompanies} */} -
{children}
-
- ); -}; - -export default CompanyLayout; +interface Props { + children: React.ReactNode; +} + +const CompanyLayout = ({ children }: Props) => { + return ( +
+ {/* {allcompanies} */} +
{children}
+
+ ); +}; + +export default CompanyLayout; diff --git a/src/app/(routes)/admin/companies/loading.tsx b/src/app/(routes)/admin/companies/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/companies/loading.tsx +++ b/src/app/(routes)/admin/companies/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/companies/page.tsx b/src/app/(routes)/admin/companies/page.tsx index 28b1b741..f4c0bae4 100644 --- a/src/app/(routes)/admin/companies/page.tsx +++ b/src/app/(routes)/admin/companies/page.tsx @@ -1,49 +1,49 @@ -"use client"; -import { fetchcompanies } from "@/helpers/api"; -import generateColumns from "@/components/NewTableComponent/ColumnMapping"; -import { companyDTO } from "@/dto/CompanyDto"; -import Table from "@/components/NewTableComponent/Table"; -import { useEffect, useState } from "react"; -import Loader from "@/components/Loader/loader"; - -const hiddenColumns = ["id"]; - -const JobPage = () => { - const columns = generateColumns(companyDTO); - const [loading, setLoading] = useState(true); - const [allCompanies, setAllCompanies] = useState(); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - useEffect(() => { - const getData = async () => { - const data = await fetchcompanies(); - setAllCompanies(data); - setLoading(false); - }; - getData(); - }, []); - - return ( -
-

Companies

-
- {loading && ( -
- -
- )} - {allCompanies && ( - - )} - - - ); -}; - -export default JobPage; +"use client"; +import { fetchcompanies } from "@/helpers/api"; +import generateColumns from "@/components/NewTableComponent/ColumnMapping"; +import { companyDTO } from "@/dto/CompanyDto"; +import Table from "@/components/NewTableComponent/Table"; +import { useEffect, useState } from "react"; +import Loader from "@/components/Loader/loader"; + +const hiddenColumns = ["id"]; + +const JobPage = () => { + const columns = generateColumns(companyDTO); + const [loading, setLoading] = useState(true); + const [allCompanies, setAllCompanies] = useState(); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + useEffect(() => { + const getData = async () => { + const data = await fetchcompanies(); + setAllCompanies(data); + setLoading(false); + }; + getData(); + }, []); + + return ( +
+

Companies

+
+ {loading && ( +
+ +
+ )} + {allCompanies && ( +
+ )} + + + ); +}; + +export default JobPage; diff --git a/src/app/(routes)/admin/jobs/[...filter]/page.tsx b/src/app/(routes)/admin/jobs/[...filter]/page.tsx index 5cda3d47..6534a258 100644 --- a/src/app/(routes)/admin/jobs/[...filter]/page.tsx +++ b/src/app/(routes)/admin/jobs/[...filter]/page.tsx @@ -1,61 +1,61 @@ -"use client"; -import { fetchAllJobs } from "@/helpers/api"; -import TableComponent from "@/components/TableComponent/TableComponent"; -import generateColumns from "@/components/TableComponent/ColumnMapping"; -import { useEffect, useState } from "react"; - -const dto = [ - { - id: "string", - seasonId: "string", - recruiterId: "string", - companyId: "string", - role: "string", - active: "boolean", - currentStatus: "string", - season: { - id: "string", - year: "string", - type: "string", - }, - company: { - id: "string", - name: "string", - }, - }, -]; - -const dynamicColumns = generateColumns(dto[0]); - -const StudentPage = ({ params }: any) => { - const [jobs, setJobs] = useState([]); - - useEffect(() => { - const fetchData = async () => { - const decodedParams = decodeURIComponent(params.filter[0]); - const AllFilteredJobs = await fetchAllJobs(decodedParams); - setJobs(AllFilteredJobs); - }; - - fetchData(); - }, [params?.filter[0]]); - - return ( -
-

Jobs Filter

-
- {jobs.length > 0 && ( - - )} -
-
- ); -}; - -export default StudentPage; +"use client"; +import { fetchAllJobs } from "@/helpers/api"; +import TableComponent from "@/components/TableComponent/TableComponent"; +import generateColumns from "@/components/TableComponent/ColumnMapping"; +import { useEffect, useState } from "react"; + +const dto = [ + { + id: "string", + seasonId: "string", + recruiterId: "string", + companyId: "string", + role: "string", + active: "boolean", + currentStatus: "string", + season: { + id: "string", + year: "string", + type: "string", + }, + company: { + id: "string", + name: "string", + }, + }, +]; + +const dynamicColumns = generateColumns(dto[0]); + +const StudentPage = ({ params }: any) => { + const [jobs, setJobs] = useState([]); + + useEffect(() => { + const fetchData = async () => { + const decodedParams = decodeURIComponent(params.filter[0]); + const AllFilteredJobs = await fetchAllJobs(decodedParams); + setJobs(AllFilteredJobs); + }; + + fetchData(); + }, [params?.filter[0]]); + + return ( +
+

Jobs Filter

+
+ {jobs.length > 0 && ( + + )} +
+
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/admin/jobs/[jobId]/layout.tsx b/src/app/(routes)/admin/jobs/[jobId]/layout.tsx index 02c5be14..c21c4010 100644 --- a/src/app/(routes)/admin/jobs/[jobId]/layout.tsx +++ b/src/app/(routes)/admin/jobs/[jobId]/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminJobLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminJobLayout; +interface Props { + children: React.ReactNode; +} + +const AdminJobLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminJobLayout; diff --git a/src/app/(routes)/admin/jobs/[jobId]/page.tsx b/src/app/(routes)/admin/jobs/[jobId]/page.tsx index 6a80331c..31b4b75e 100644 --- a/src/app/(routes)/admin/jobs/[jobId]/page.tsx +++ b/src/app/(routes)/admin/jobs/[jobId]/page.tsx @@ -1,1517 +1,1517 @@ -"use client"; -import React, { useState, useEffect } from "react"; -import { JobDetailFC } from "@/helpers/recruiter/types"; -import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; -import PersonIcon from "@mui/icons-material/Person"; -import { Button } from "@/components/ui/button"; -import Link from "next/link"; -import { Separator } from "@/components/ui/separator"; -import { getJafDetails } from "@/helpers/recruiter/api"; -import { JAFdetailsFC } from "@/helpers/recruiter/types"; -import { patchJobData } from "@/helpers/api"; -import { patchSalaryData } from "@/helpers/api"; -import { - CategorySelectList, - GenderSelectList, -} from "@/components/Recruiters/jobEdit"; -import { fetchJobById } from "@/helpers/api"; -import Loader from "@/components/Loader/loader"; -import toast from "react-hot-toast"; -import JobCoordinatorForm from "@/components/Admin/AddForms"; -import { fetchCompany, fetchRecruiterData, fetchFaculties, postFacultyApproval } from "@/helpers/api"; -import { assignCompany, postCompany, assignRecruiter, postRecruiter, fetchApprovals } from "@/helpers/api"; -import Select from "react-select"; -const currentStatusOptions = [ - "INITIALIZED", - "SCHEDULED", - "PPT_DONE", - "POLL_FREEZED", - "TEST_COMPLETED", - "INTERVIEW_COMPLETED", - "RECRUITMENT_PROCESS_COMPLELETED", - "OFFER_LETTER_RELEASED", - "PROCESS_ON_HOLD", - "PROCESS_TERMINATED", - "OFFER_REVOKED", -]; - - -const JobDetailPage = ({ params }: { params: { jobId: string } }) => { - const [job, setData] = useState(null); - const [loading, setLoading] = useState(true); - const [editMode, setEditMode] = useState(false); - const [formData, setFormData] = useState(null); - const [jafDetails, setJafDetails] = useState(); - const [facultyData, setFacultyData] = useState(null); - const [facultyApprovals, setFacultyApprovals] = useState([]); - const [selectedFaculties, setSelectedFaculties] = useState([]); - const [facultyDropDown, setFacultyDropdown] = useState([false]); - const [companyData, setCompanyData] = useState(null); - const [recruiterData, setRecruiterData] = useState(null); - const [companyDropDown, setcompanyDropDown] = useState(false); - const [recruiterDropDown, setrecruiterDropDown] = useState(false); - const [selectedCompany, setSelectedCompany] = useState(null); - const [selectedRecruiter, setSelectedRecruiter] = useState(null); - const [toggleCompanyModal, setToggleCompanyModal] = useState(false); - const [toggleRecruiterModal, setToggleRecruiterModal] = useState(false); - const [approvalModal, setApprovalModal] = useState(false); - const [companyFormData, setCompanyFormData] = useState({ - name: '', - size: 0, - category: '', - yearOfEstablishment: '', - website: '', - annualTurnover: '', - socialMediaLink: '', - address: { - line1: '', - line2: '', - city: '', - state: '', - country: '' - }, - domains: [''] - }); - const [recruiterFormData, setRecruiterFormData] = useState({ - designation: '', - landline: '', - companyId: '', - user: { - name: '', - email: '', - contact: '' - } - }); - const newCurrentStatusOptions = currentStatusOptions.map((option) => ({ - value: option, - label: option, - })); - - useEffect(() => { - const fetchData = async () => { - try { - - const [jobDetailData, jafDetailsData, companyData, recruiterData, facultyData] = - await Promise.all([ - fetchJobById(params.jobId), - getJafDetails(), - fetchCompany(), - fetchRecruiterData(), - fetchFaculties(), - ]); - - setJafDetails(jafDetailsData); - setData(jobDetailData); - setFormData(jobDetailData); - setFacultyData(facultyData); - setCompanyData(companyData); - setRecruiterData(recruiterData); - setRecruiterFormData({ - designation: jobDetailData.recruiterDetailsFilled.designation, - landline: jobDetailData.recruiterDetailsFilled.landline, - companyId: jobDetailData.company.id, // Assuming you have a companyId in jobDetailData - user: { - name: jobDetailData.recruiterDetailsFilled.name, - email: jobDetailData.recruiterDetailsFilled.email, - contact: jobDetailData.recruiterDetailsFilled.contact - } - }); - setCompanyFormData({ - name: jobDetailData.companyDetailsFilled.name, - size: jobDetailData.companyDetailsFilled.size, - category: jobDetailData.companyDetailsFilled.category, - yearOfEstablishment: jobDetailData.companyDetailsFilled.yearOfEstablishment, - website: jobDetailData.companyDetailsFilled.website, - annualTurnover: jobDetailData.companyDetailsFilled.annualTurnover || '', - socialMediaLink: jobDetailData.companyDetailsFilled.socialMediaLink || '', - address: { - line1: jobDetailData.companyDetailsFilled.address.line1 || '', - line2: jobDetailData.companyDetailsFilled.address.line2 || '', - city: jobDetailData.companyDetailsFilled.address.city || '', - state: jobDetailData.companyDetailsFilled.address.state || '', - country: jobDetailData.companyDetailsFilled.address.country || '' - }, - domains: jobDetailData.companyDetailsFilled.domains || [''] - }); - - const matchedCompany = companyData.find( - (company) => company.id === jobDetailData.company.id, - ); - setSelectedCompany(matchedCompany); - const matchedRecruiter = recruiterData.find( - (recruiter) => recruiter.id === jobDetailData.recruiter.id, - ); - setSelectedRecruiter(matchedRecruiter); - } catch (error) { - toast.error("Error fetching data"); - } finally { - setLoading(false); - } - }; - fetchData(); - }, [params.jobId]); - - const handleCompanyFormChange = (e) => { - const { name, value } = e.target; - setCompanyFormData((prevFormData) => ({ - ...prevFormData, - [name]: value, - })); - }; - - const handleRecruiterFormChange = (e) => { - const { name, value } = e.target; - const [mainKey, subKey] = name.split('.'); - - if (subKey) { - setRecruiterFormData((prevFormData) => ({ - ...prevFormData, - [mainKey]: { - ...prevFormData[mainKey], - [subKey]: value - } - })); - } else { - setRecruiterFormData((prevFormData) => ({ - ...prevFormData, - [name]: value - })); - } - }; - - const handleCompanyFormSubmit = async () => { - try { - await postCompany([{ - name: companyFormData.name, - category: companyFormData.category, - yearOfEstablishment: companyFormData.yearOfEstablishment, - website: companyFormData.website, - size: companyFormData.size, - annualTurnover: companyFormData.annualTurnover, - socialMediaLink: "companyFormData.socialMediaLink", - domains: companyFormData.domains, - address: { - line1: companyFormData.address.line1, - line2: companyFormData.address.line2, - city: companyFormData.address.city, - state: companyFormData.address.state, - country: companyFormData.address.country - } - }]); - toast.success("Company details updated successfully!"); - window.location.reload(); - } catch (error) { - toast.error("Error updating company details"); - } - }; - - const handleRecruiterFormSubmit = async () => { - try { - await postRecruiter([{ - designation: recruiterFormData.designation, - landline: recruiterFormData.landline, - companyId: recruiterFormData.companyId, - user: { - name: recruiterFormData.user.name, - email: recruiterFormData.user.email, - contact: recruiterFormData.user.contact - } - }]); - toast.success("Recruiter details updated successfully!"); - window.location.reload(); - } catch (error) { - toast.error("Error updating recruiter details"); - } - }; - const handleToggleModal = (type) => { - if (type === "company") { - setToggleCompanyModal(prevState => !prevState); - } else if (type === "recruiter") { - setToggleRecruiterModal(prevState => !prevState); - } - }; - const toggleDropdown = (state: string) => { - if (state === "company") { - setcompanyDropDown(!companyDropDown); - setrecruiterDropDown(false); - } else { - setrecruiterDropDown(!recruiterDropDown); - setcompanyDropDown(false); - } - }; - - const handleCompanySelect = (company) => { - setSelectedCompany(company); - setcompanyDropDown(false); - }; - const handleRecruiterSelect = (recruiter) => { - setSelectedRecruiter(recruiter); - setrecruiterDropDown(false); - }; - - const updateFacultyDropDown = (index, value) => { - setFacultyDropdown(prevState => { - const newState = [...prevState]; - newState[index] = value; - return newState; - }); - }; - - const submitApproval = async (salaryIndex) => { - const selected = selectedFaculties[salaryIndex] || []; - const res = await postFacultyApproval(job.salaries[salaryIndex].id, selected); - if(res) toast.success("Request Sent"); - else toast.error("Error Sending Request"); - updateFacultyDropDown(salaryIndex, false); - }; - - const getApprovals = async (salaryIndex) => { - setLoading(true); - const approvals = await fetchApprovals(job.salaries[salaryIndex].id); - setFacultyApprovals(approvals); - setLoading(false); - }; - - const handleEditClick = () => { - if (editMode) { - handleSubmit(); - } - setEditMode(!editMode); - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ ...prev, [name]: value })); - }; - - const handleSubmit = async () => { - await patchJobData(job.id, formData); - formData.salaries.map((salary, index) => patchSalaryData(salary)); - setEditMode(false); - window.location.reload(); - }; - - const addNewTest = () => { - const newTest = { type: "", duration: 0 }; - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - tests: [...prev.selectionProcedure.tests, newTest], - }, - })); - }; - - const addNewInterview = () => { - const newInterview = { type: "", duration: 0 }; - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - interviews: [...prev.selectionProcedure.interviews, newInterview], - }, - })); - }; - - return ( -
- {loading && ( -
-
- -
-
- )} - {job && ( -
-
-
-
- Role - {editMode ? ( - - ) : ( - {job.role} - )} -
-
- Activity - {editMode ? ( - { - setFormData((form) => ({ - ...form, - active: e.target.checked, - })); - }} - /> - ) : ( - {job.active ? "Active" : "Inactive"} - )} -
-
- Current Status - {editMode ? ( - - ) : ( - job.skills - )} -
-
-
-
Location
{" "} - {editMode ? ( - - ) : ( -
{job.location}
- )} -
-
-
Offer letter release
{" "} - {editMode ? ( - - ) : ( -
- {new Date(job.offerLetterReleaseDate).toLocaleString()} -
- )} -
-
-
Joining Date
{" "} - {editMode ? ( - - ) : ( -
{new Date(job.joiningDate).toLocaleString()}
- )} -
-
-
Duration
{" "} - {editMode ? ( - - ) : ( -
{job.duration}
- )} -
-
-
Attachment
{" "} - {editMode ? ( - - ) : ( -
{job.attachment}
- )} -
-
-
-
-
-
-
Company Details
-
-
-
Company Name
-
- {companyDropDown ? ( -
- toggleDropdown("company")} - readOnly - /> - {companyDropDown && ( -
-
- {companyData.map((company) => ( -
handleCompanySelect(company)} - > - {company.name} -
- ))} -
-
- -
-
- {toggleCompanyModal && ( -
-
-
-

Edit Company Details

- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- -
-
-
- )} - -
- -
- )} -
- ) : ( -
-
toggleDropdown("company")} - className="cursor-pointer w-full" - > - {selectedCompany?.name || "Select a Company"} -
- -
- )} -
-
-
-
Annual Turnover
-
-
{selectedCompany?.annualTurnover}
-
-
-
-
- Year of Establishment -
-
-
{selectedCompany?.yearOfEstablishment}
-
-
-
-
Category
-
-
{selectedCompany?.category}
-
-
-
-
Social Media Link
- -
-
- -
-
-
-
-
-
Recruiter Details
-
-
-
Recruiter Name
-
- {recruiterDropDown ? ( -
- toggleDropdown("recruiter")} - readOnly - /> - {recruiterDropDown && ( -
-
- {recruiterData.map((recruiter) => ( -
handleRecruiterSelect(recruiter)} - > - {recruiter.user.name} -
- ))} -
-
- -
-
- {toggleRecruiterModal && ( -
-
-
-

Edit Recruiter Details

- -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- -
-
-
- )} - - - -
- -
- )} -
- ) : ( -
-
toggleDropdown("recruiter")} - className="cursor-pointer w-full" - > - {selectedRecruiter?.user.name || "Select a Recruiter"} -
- -
- )} -
-
- -
-
Name
-
-
{selectedRecruiter?.user.name}
-
-
-
-
Email
-
-
{selectedRecruiter?.user.email}
-
-
-
-
Contact
-
-
{selectedRecruiter?.user.contact}
-
-
-
-
Company
-
-
{selectedRecruiter?.company.name}
-
-
-
-
Designation
-
-
{selectedRecruiter?.designation}
-
-
-
- -
-
-
- - {job.selectionProcedure && ( -
-
- Selection Procedure -
- -
-
-
Selection mode
{" "} - {editMode ? ( - - ) : ( -
{job.selectionProcedure.selectionMode}
- )} -
-
-
- Shortlist from Resume -
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - shortlistFromResume: e.target.checked, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.shortlistFromResume - ? "YES" - : "NO"} -
- )} -
-
-
Group Discussion
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - groupDiscussion: e.target.checked, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.groupDiscussion ? "YES" : "NO"} -
- )} -
-
-
Number of members
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - requirements: { - ...prev.selectionProcedure.requirements, - numberOfMembers: e.target.value, - }, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.requirements?.numberOfMembers!} -
- )} -
-
- -
-
-
Tests
-
    - {editMode - ? formData.selectionProcedure.tests.map((test, index) => ( -
  • - Test Type: - -
    - Test Duration: - { - const updatedTests = - formData.selectionProcedure.tests.map( - (t, i) => - i === index - ? { - ...t, - duration: Number(e.target.value), - } - : t, - ); - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - tests: updatedTests, - }, - })); - }} - /> -
  • - )) - : job.selectionProcedure.tests.map((p, index) => ( -
  • - {Object.entries(p).map(([key, value]) => ( - - {key} : {value} -
    -
    - ))} -
  • - ))} -
- {editMode && ( - - )} -
- - - -
-
Interviews
-
    - {editMode - ? formData.selectionProcedure.interviews.map( - (interview, index) => ( -
  • - Interview Type: - -
    - Interview Duration: - { - const updatedInterviews = - formData.selectionProcedure.interviews.map( - (i, j) => - j === index - ? { ...i, duration: e.target.value } - : i, - ); - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - interviews: updatedInterviews, - }, - })); - }} - /> -
  • - ), - ) - : job.selectionProcedure.interviews.map((p, index) => ( -
  • - {Object.entries(p).map(([key, value]) => ( - - {key} : {value} -
    -
    - ))} -
  • - ))} -
- {editMode && ( - - )} -
-
-
-
-
- Other requirements :{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - requirements: { - ...prev.selectionProcedure.requirements, - otherRequirements: e.target.value, - }, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.requirements?.otherRequirements} -
- )} -
-
-
-
- )} -
-
Job Coordinators
-
- {job.jobCoordinators?.map((coordinator, index) => ( -
-
- -
- {coordinator.tpcMember.student.user.name} -
-
-
- Role : - {coordinator.tpcMember.role} -
-
- Department : - {coordinator.tpcMember.student.program.department} -
-
- Email : - {coordinator.tpcMember.student.user.email} -
-
- Contact : - {coordinator.tpcMember.student.user.contact} -
-
-
- ))} - -
-
-
-
-
Salaries
- -
- {job.salaries?.map((salary, salaryIndex) => ( - <> -
-
-
-
Base Salary
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, baseSalary: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.baseSalary}
- )} -
-
-
CTC
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, totalCTC: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.totalCTC}
- )} -
-
-
Take Home Salary
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, takeHomeSalary: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.takeHomeSalary}
- )} -
-
-
Gross Salary
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, grossSalary: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.grossSalary}
- )} -
-
-
Other Compensations
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, otherCompensations: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.otherCompensations}
- )} -
-
-
-
-
Minimum CPI
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, minCPI: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.minCPI}
- )} -
-
-
Tenth Marks
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, tenthMarks: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.tenthMarks}
- )} -
-
-
TwelthMarks Marks
- {editMode ? ( - { - const updatedSalaries = formData.salaries.map((s, i) => - i === salaryIndex ? { ...s, twelthMarks: e.target.value } : s - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.twelthMarks}
- )} -
-
- {/* Genders */} -
-

Genders

- {editMode ? ( - - ) : ( -
- {salary.genders?.map((gender, genderIndex) => ( -
- {editMode ? null : ( -
- {gender} -
- )} -
- ))} -
- )} -
- - {/* Categories */} -
-

Categories

- {editMode ? ( - - ) : ( -
- {salary.categories?.map((category, categoryIndex) => ( -
- {editMode ? null : ( -
- {category} -
- )} -
- ))} -
- )} -
- {/* */} -
- -
- {facultyDropDown[salaryIndex] && ()} - -
-
- - {approvalModal && ( -
-
-
-

Current Approvals

- -
-
- {loading ? ( - - ) : ( - facultyApprovals.map((approval, salaryIndex) => ( -
-

{approval?.faculty.user.name}

-

Department: {approval.faculty.department}

-

Email: {approval.faculty?.user.email}

-

Contact: {approval.faculty?.user.contact}

-

Status: {approval.status}

-
- )) - )} -
-
-
- )} - -
-
- - {facultyDropDown[salaryIndex] && ( - <>
- {facultyData.map((faculty) => ( - - ))} -
- )} -
-
-
- ))} -
-
- ) - } -
- ); -}; - -export default JobDetailPage; +"use client"; +import React, { useState, useEffect } from "react"; +import { JobDetailFC } from "@/helpers/recruiter/types"; +import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; +import PersonIcon from "@mui/icons-material/Person"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { Separator } from "@/components/ui/separator"; +import { getJafDetails } from "@/helpers/recruiter/api"; +import { JAFdetailsFC } from "@/helpers/recruiter/types"; +import { patchJobData } from "@/helpers/api"; +import { patchSalaryData } from "@/helpers/api"; +import { + CategorySelectList, + GenderSelectList, +} from "@/components/Recruiters/jobEdit"; +import { fetchJobById } from "@/helpers/api"; +import Loader from "@/components/Loader/loader"; +import toast from "react-hot-toast"; +import JobCoordinatorForm from "@/components/Admin/AddForms"; +import { fetchCompany, fetchRecruiterData, fetchFaculties, postFacultyApproval } from "@/helpers/api"; +import { assignCompany, postCompany, assignRecruiter, postRecruiter, fetchApprovals } from "@/helpers/api"; +import Select from "react-select"; +const currentStatusOptions = [ + "INITIALIZED", + "SCHEDULED", + "PPT_DONE", + "POLL_FREEZED", + "TEST_COMPLETED", + "INTERVIEW_COMPLETED", + "RECRUITMENT_PROCESS_COMPLELETED", + "OFFER_LETTER_RELEASED", + "PROCESS_ON_HOLD", + "PROCESS_TERMINATED", + "OFFER_REVOKED", +]; + + +const JobDetailPage = ({ params }: { params: { jobId: string } }) => { + const [job, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [editMode, setEditMode] = useState(false); + const [formData, setFormData] = useState(null); + const [jafDetails, setJafDetails] = useState(); + const [facultyData, setFacultyData] = useState(null); + const [facultyApprovals, setFacultyApprovals] = useState([]); + const [selectedFaculties, setSelectedFaculties] = useState([]); + const [facultyDropDown, setFacultyDropdown] = useState([false]); + const [companyData, setCompanyData] = useState(null); + const [recruiterData, setRecruiterData] = useState(null); + const [companyDropDown, setcompanyDropDown] = useState(false); + const [recruiterDropDown, setrecruiterDropDown] = useState(false); + const [selectedCompany, setSelectedCompany] = useState(null); + const [selectedRecruiter, setSelectedRecruiter] = useState(null); + const [toggleCompanyModal, setToggleCompanyModal] = useState(false); + const [toggleRecruiterModal, setToggleRecruiterModal] = useState(false); + const [approvalModal, setApprovalModal] = useState(false); + const [companyFormData, setCompanyFormData] = useState({ + name: '', + size: 0, + category: '', + yearOfEstablishment: '', + website: '', + annualTurnover: '', + socialMediaLink: '', + address: { + line1: '', + line2: '', + city: '', + state: '', + country: '' + }, + domains: [''] + }); + const [recruiterFormData, setRecruiterFormData] = useState({ + designation: '', + landline: '', + companyId: '', + user: { + name: '', + email: '', + contact: '' + } + }); + const newCurrentStatusOptions = currentStatusOptions.map((option) => ({ + value: option, + label: option, + })); + + useEffect(() => { + const fetchData = async () => { + try { + + const [jobDetailData, jafDetailsData, companyData, recruiterData, facultyData] = + await Promise.all([ + fetchJobById(params.jobId), + getJafDetails(), + fetchCompany(), + fetchRecruiterData(), + fetchFaculties(), + ]); + + setJafDetails(jafDetailsData); + setData(jobDetailData); + setFormData(jobDetailData); + setFacultyData(facultyData); + setCompanyData(companyData); + setRecruiterData(recruiterData); + setRecruiterFormData({ + designation: jobDetailData.recruiterDetailsFilled.designation, + landline: jobDetailData.recruiterDetailsFilled.landline, + companyId: jobDetailData.company.id, // Assuming you have a companyId in jobDetailData + user: { + name: jobDetailData.recruiterDetailsFilled.name, + email: jobDetailData.recruiterDetailsFilled.email, + contact: jobDetailData.recruiterDetailsFilled.contact + } + }); + setCompanyFormData({ + name: jobDetailData.companyDetailsFilled.name, + size: jobDetailData.companyDetailsFilled.size, + category: jobDetailData.companyDetailsFilled.category, + yearOfEstablishment: jobDetailData.companyDetailsFilled.yearOfEstablishment, + website: jobDetailData.companyDetailsFilled.website, + annualTurnover: jobDetailData.companyDetailsFilled.annualTurnover || '', + socialMediaLink: jobDetailData.companyDetailsFilled.socialMediaLink || '', + address: { + line1: jobDetailData.companyDetailsFilled.address.line1 || '', + line2: jobDetailData.companyDetailsFilled.address.line2 || '', + city: jobDetailData.companyDetailsFilled.address.city || '', + state: jobDetailData.companyDetailsFilled.address.state || '', + country: jobDetailData.companyDetailsFilled.address.country || '' + }, + domains: jobDetailData.companyDetailsFilled.domains || [''] + }); + + const matchedCompany = companyData.find( + (company) => company.id === jobDetailData.company.id, + ); + setSelectedCompany(matchedCompany); + const matchedRecruiter = recruiterData.find( + (recruiter) => recruiter.id === jobDetailData.recruiter.id, + ); + setSelectedRecruiter(matchedRecruiter); + } catch (error) { + toast.error("Error fetching data"); + } finally { + setLoading(false); + } + }; + fetchData(); + }, [params.jobId]); + + const handleCompanyFormChange = (e) => { + const { name, value } = e.target; + setCompanyFormData((prevFormData) => ({ + ...prevFormData, + [name]: value, + })); + }; + + const handleRecruiterFormChange = (e) => { + const { name, value } = e.target; + const [mainKey, subKey] = name.split('.'); + + if (subKey) { + setRecruiterFormData((prevFormData) => ({ + ...prevFormData, + [mainKey]: { + ...prevFormData[mainKey], + [subKey]: value + } + })); + } else { + setRecruiterFormData((prevFormData) => ({ + ...prevFormData, + [name]: value + })); + } + }; + + const handleCompanyFormSubmit = async () => { + try { + await postCompany([{ + name: companyFormData.name, + category: companyFormData.category, + yearOfEstablishment: companyFormData.yearOfEstablishment, + website: companyFormData.website, + size: companyFormData.size, + annualTurnover: companyFormData.annualTurnover, + socialMediaLink: "companyFormData.socialMediaLink", + domains: companyFormData.domains, + address: { + line1: companyFormData.address.line1, + line2: companyFormData.address.line2, + city: companyFormData.address.city, + state: companyFormData.address.state, + country: companyFormData.address.country + } + }]); + toast.success("Company details updated successfully!"); + window.location.reload(); + } catch (error) { + toast.error("Error updating company details"); + } + }; + + const handleRecruiterFormSubmit = async () => { + try { + await postRecruiter([{ + designation: recruiterFormData.designation, + landline: recruiterFormData.landline, + companyId: recruiterFormData.companyId, + user: { + name: recruiterFormData.user.name, + email: recruiterFormData.user.email, + contact: recruiterFormData.user.contact + } + }]); + toast.success("Recruiter details updated successfully!"); + window.location.reload(); + } catch (error) { + toast.error("Error updating recruiter details"); + } + }; + const handleToggleModal = (type) => { + if (type === "company") { + setToggleCompanyModal(prevState => !prevState); + } else if (type === "recruiter") { + setToggleRecruiterModal(prevState => !prevState); + } + }; + const toggleDropdown = (state: string) => { + if (state === "company") { + setcompanyDropDown(!companyDropDown); + setrecruiterDropDown(false); + } else { + setrecruiterDropDown(!recruiterDropDown); + setcompanyDropDown(false); + } + }; + + const handleCompanySelect = (company) => { + setSelectedCompany(company); + setcompanyDropDown(false); + }; + const handleRecruiterSelect = (recruiter) => { + setSelectedRecruiter(recruiter); + setrecruiterDropDown(false); + }; + + const updateFacultyDropDown = (index, value) => { + setFacultyDropdown(prevState => { + const newState = [...prevState]; + newState[index] = value; + return newState; + }); + }; + + const submitApproval = async (salaryIndex) => { + const selected = selectedFaculties[salaryIndex] || []; + const res = await postFacultyApproval(job.salaries[salaryIndex].id, selected); + if(res) toast.success("Request Sent"); + else toast.error("Error Sending Request"); + updateFacultyDropDown(salaryIndex, false); + }; + + const getApprovals = async (salaryIndex) => { + setLoading(true); + const approvals = await fetchApprovals(job.salaries[salaryIndex].id); + setFacultyApprovals(approvals); + setLoading(false); + }; + + const handleEditClick = () => { + if (editMode) { + handleSubmit(); + } + setEditMode(!editMode); + }; + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleSubmit = async () => { + await patchJobData(job.id, formData); + formData.salaries.map((salary, index) => patchSalaryData(salary)); + setEditMode(false); + window.location.reload(); + }; + + const addNewTest = () => { + const newTest = { type: "", duration: 0 }; + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + tests: [...prev.selectionProcedure.tests, newTest], + }, + })); + }; + + const addNewInterview = () => { + const newInterview = { type: "", duration: 0 }; + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + interviews: [...prev.selectionProcedure.interviews, newInterview], + }, + })); + }; + + return ( +
+ {loading && ( +
+
+ +
+
+ )} + {job && ( +
+
+
+
+ Role + {editMode ? ( + + ) : ( + {job.role} + )} +
+
+ Activity + {editMode ? ( + { + setFormData((form) => ({ + ...form, + active: e.target.checked, + })); + }} + /> + ) : ( + {job.active ? "Active" : "Inactive"} + )} +
+
+ Current Status + {editMode ? ( + + ) : ( + job.skills + )} +
+
+
+
Location
{" "} + {editMode ? ( + + ) : ( +
{job.location}
+ )} +
+
+
Offer letter release
{" "} + {editMode ? ( + + ) : ( +
+ {new Date(job.offerLetterReleaseDate).toLocaleString()} +
+ )} +
+
+
Joining Date
{" "} + {editMode ? ( + + ) : ( +
{new Date(job.joiningDate).toLocaleString()}
+ )} +
+
+
Duration
{" "} + {editMode ? ( + + ) : ( +
{job.duration}
+ )} +
+
+
Attachment
{" "} + {editMode ? ( + + ) : ( +
{job.attachment}
+ )} +
+
+
+
+
+
+
Company Details
+
+
+
Company Name
+
+ {companyDropDown ? ( +
+ toggleDropdown("company")} + readOnly + /> + {companyDropDown && ( +
+
+ {companyData.map((company) => ( +
handleCompanySelect(company)} + > + {company.name} +
+ ))} +
+
+ +
+
+ {toggleCompanyModal && ( +
+
+
+

Edit Company Details

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
+
+ )} + +
+ +
+ )} +
+ ) : ( +
+
toggleDropdown("company")} + className="cursor-pointer w-full" + > + {selectedCompany?.name || "Select a Company"} +
+ +
+ )} +
+
+
+
Annual Turnover
+
+
{selectedCompany?.annualTurnover}
+
+
+
+
+ Year of Establishment +
+
+
{selectedCompany?.yearOfEstablishment}
+
+
+
+
Category
+
+
{selectedCompany?.category}
+
+
+
+
Social Media Link
+ +
+
+ +
+
+
+
+
+
Recruiter Details
+
+
+
Recruiter Name
+
+ {recruiterDropDown ? ( +
+ toggleDropdown("recruiter")} + readOnly + /> + {recruiterDropDown && ( +
+
+ {recruiterData.map((recruiter) => ( +
handleRecruiterSelect(recruiter)} + > + {recruiter.user.name} +
+ ))} +
+
+ +
+
+ {toggleRecruiterModal && ( +
+
+
+

Edit Recruiter Details

+ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
+
+ )} + + + +
+ +
+ )} +
+ ) : ( +
+
toggleDropdown("recruiter")} + className="cursor-pointer w-full" + > + {selectedRecruiter?.user.name || "Select a Recruiter"} +
+ +
+ )} +
+
+ +
+
Name
+
+
{selectedRecruiter?.user.name}
+
+
+
+
Email
+
+
{selectedRecruiter?.user.email}
+
+
+
+
Contact
+
+
{selectedRecruiter?.user.contact}
+
+
+
+
Company
+
+
{selectedRecruiter?.company.name}
+
+
+
+
Designation
+
+
{selectedRecruiter?.designation}
+
+
+
+ +
+
+
+ + {job.selectionProcedure && ( +
+
+ Selection Procedure +
+ +
+
+
Selection mode
{" "} + {editMode ? ( + + ) : ( +
{job.selectionProcedure.selectionMode}
+ )} +
+
+
+ Shortlist from Resume +
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + shortlistFromResume: e.target.checked, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.shortlistFromResume + ? "YES" + : "NO"} +
+ )} +
+
+
Group Discussion
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + groupDiscussion: e.target.checked, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.groupDiscussion ? "YES" : "NO"} +
+ )} +
+
+
Number of members
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + requirements: { + ...prev.selectionProcedure.requirements, + numberOfMembers: e.target.value, + }, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.requirements?.numberOfMembers!} +
+ )} +
+
+ +
+
+
Tests
+
    + {editMode + ? formData.selectionProcedure.tests.map((test, index) => ( +
  • + Test Type: + +
    + Test Duration: + { + const updatedTests = + formData.selectionProcedure.tests.map( + (t, i) => + i === index + ? { + ...t, + duration: Number(e.target.value), + } + : t, + ); + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + tests: updatedTests, + }, + })); + }} + /> +
  • + )) + : job.selectionProcedure.tests.map((p, index) => ( +
  • + {Object.entries(p).map(([key, value]) => ( + + {key} : {value} +
    +
    + ))} +
  • + ))} +
+ {editMode && ( + + )} +
+ + + +
+
Interviews
+
    + {editMode + ? formData.selectionProcedure.interviews.map( + (interview, index) => ( +
  • + Interview Type: + +
    + Interview Duration: + { + const updatedInterviews = + formData.selectionProcedure.interviews.map( + (i, j) => + j === index + ? { ...i, duration: e.target.value } + : i, + ); + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + interviews: updatedInterviews, + }, + })); + }} + /> +
  • + ), + ) + : job.selectionProcedure.interviews.map((p, index) => ( +
  • + {Object.entries(p).map(([key, value]) => ( + + {key} : {value} +
    +
    + ))} +
  • + ))} +
+ {editMode && ( + + )} +
+
+
+
+
+ Other requirements :{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + requirements: { + ...prev.selectionProcedure.requirements, + otherRequirements: e.target.value, + }, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.requirements?.otherRequirements} +
+ )} +
+
+
+
+ )} +
+
Job Coordinators
+
+ {job.jobCoordinators?.map((coordinator, index) => ( +
+
+ +
+ {coordinator.tpcMember.student.user.name} +
+
+
+ Role : + {coordinator.tpcMember.role} +
+
+ Department : + {coordinator.tpcMember.student.program.department} +
+
+ Email : + {coordinator.tpcMember.student.user.email} +
+
+ Contact : + {coordinator.tpcMember.student.user.contact} +
+
+
+ ))} + +
+
+
+
+
Salaries
+ +
+ {job.salaries?.map((salary, salaryIndex) => ( + <> +
+
+
+
Base Salary
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, baseSalary: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.baseSalary}
+ )} +
+
+
CTC
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, totalCTC: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.totalCTC}
+ )} +
+
+
Take Home Salary
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, takeHomeSalary: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.takeHomeSalary}
+ )} +
+
+
Gross Salary
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, grossSalary: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.grossSalary}
+ )} +
+
+
Other Compensations
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, otherCompensations: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.otherCompensations}
+ )} +
+
+
+
+
Minimum CPI
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, minCPI: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.minCPI}
+ )} +
+
+
Tenth Marks
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, tenthMarks: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.tenthMarks}
+ )} +
+
+
TwelthMarks Marks
+ {editMode ? ( + { + const updatedSalaries = formData.salaries.map((s, i) => + i === salaryIndex ? { ...s, twelthMarks: e.target.value } : s + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.twelthMarks}
+ )} +
+
+ {/* Genders */} +
+

Genders

+ {editMode ? ( + + ) : ( +
+ {salary.genders?.map((gender, genderIndex) => ( +
+ {editMode ? null : ( +
+ {gender} +
+ )} +
+ ))} +
+ )} +
+ + {/* Categories */} +
+

Categories

+ {editMode ? ( + + ) : ( +
+ {salary.categories?.map((category, categoryIndex) => ( +
+ {editMode ? null : ( +
+ {category} +
+ )} +
+ ))} +
+ )} +
+ {/* */} +
+ +
+ {facultyDropDown[salaryIndex] && ()} + +
+
+ + {approvalModal && ( +
+
+
+

Current Approvals

+ +
+
+ {loading ? ( + + ) : ( + facultyApprovals.map((approval, salaryIndex) => ( +
+

{approval?.faculty.user.name}

+

Department: {approval.faculty.department}

+

Email: {approval.faculty?.user.email}

+

Contact: {approval.faculty?.user.contact}

+

Status: {approval.status}

+
+ )) + )} +
+
+
+ )} + +
+
+ + {facultyDropDown[salaryIndex] && ( + <>
+ {facultyData.map((faculty) => ( + + ))} +
+ )} +
+
+
+ ))} +
+
+ ) + } +
+ ); +}; + +export default JobDetailPage; diff --git a/src/app/(routes)/admin/jobs/events/[jobId]/layout.tsx b/src/app/(routes)/admin/jobs/events/[jobId]/layout.tsx index 02c5be14..c21c4010 100644 --- a/src/app/(routes)/admin/jobs/events/[jobId]/layout.tsx +++ b/src/app/(routes)/admin/jobs/events/[jobId]/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminJobLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminJobLayout; +interface Props { + children: React.ReactNode; +} + +const AdminJobLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminJobLayout; diff --git a/src/app/(routes)/admin/jobs/events/[jobId]/page.tsx b/src/app/(routes)/admin/jobs/events/[jobId]/page.tsx index b85473a5..b87acaa5 100644 --- a/src/app/(routes)/admin/jobs/events/[jobId]/page.tsx +++ b/src/app/(routes)/admin/jobs/events/[jobId]/page.tsx @@ -1,66 +1,66 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import { JobEvents } from "@/components/Admin/JobEvents"; -import { fetchJobEvents } from "@/helpers/api"; -import { EventFC } from "@/helpers/recruiter/types"; -import { Button } from "@/components/ui/button"; -import { AddEvent } from "@/components/Admin/JobEvents"; -import Loader from "@/components/Loader/loader"; -import toast from "react-hot-toast"; - -const EventsPage = ({ params }: { params: { jobId: string } }) => { - const [events, setData] = useState<[EventFC]>(null); - const [loading, setLoading] = useState(true); - const [addEventForm, setAddEventForm] = useState(false); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await fetchJobEvents(params.jobId); - setData(jsonData); - } catch (error) { - toast.error("Some error occured"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [params.jobId]); - return ( -
-

- Events And Applications -

- {addEventForm && ( - - )} -
- -
- {loading && ( -
- -
- )} - {events && ( -
- -
- )} -
- ); -}; - -export default EventsPage; +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { JobEvents } from "@/components/Admin/JobEvents"; +import { fetchJobEvents } from "@/helpers/api"; +import { EventFC } from "@/helpers/recruiter/types"; +import { Button } from "@/components/ui/button"; +import { AddEvent } from "@/components/Admin/JobEvents"; +import Loader from "@/components/Loader/loader"; +import toast from "react-hot-toast"; + +const EventsPage = ({ params }: { params: { jobId: string } }) => { + const [events, setData] = useState<[EventFC]>(null); + const [loading, setLoading] = useState(true); + const [addEventForm, setAddEventForm] = useState(false); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await fetchJobEvents(params.jobId); + setData(jsonData); + } catch (error) { + toast.error("Some error occured"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [params.jobId]); + return ( +
+

+ Events And Applications +

+ {addEventForm && ( + + )} +
+ +
+ {loading && ( +
+ +
+ )} + {events && ( +
+ +
+ )} +
+ ); +}; + +export default EventsPage; diff --git a/src/app/(routes)/admin/jobs/layout.tsx b/src/app/(routes)/admin/jobs/layout.tsx index f7176067..c159f1f8 100644 --- a/src/app/(routes)/admin/jobs/layout.tsx +++ b/src/app/(routes)/admin/jobs/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminJobLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminJobLayout; +interface Props { + children: React.ReactNode; +} + +const AdminJobLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminJobLayout; diff --git a/src/app/(routes)/admin/jobs/loading.tsx b/src/app/(routes)/admin/jobs/loading.tsx index 42cbb5c0..f815b8a3 100644 --- a/src/app/(routes)/admin/jobs/loading.tsx +++ b/src/app/(routes)/admin/jobs/loading.tsx @@ -1,28 +1,28 @@ -"use client"; - -import React, { Component } from "react"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/jobs/page.tsx b/src/app/(routes)/admin/jobs/page.tsx index 5f445fbb..f219fde4 100644 --- a/src/app/(routes)/admin/jobs/page.tsx +++ b/src/app/(routes)/admin/jobs/page.tsx @@ -1,57 +1,57 @@ -"use client"; -import { fetchAllJobs } from "@/helpers/api"; -import generateColumns from "@/components/NewTableComponent/ColumnMapping"; -import type { RecruitmentDTO } from "@/dto/JobDto"; -import { recruitmentDTO } from "@/dto/JobDto"; -import { createMRTColumnHelper } from "material-react-table"; -import Table from "@/components/NewTableComponent/Table"; -import { useEffect, useState } from "react"; -import Loader from "@/components/Loader/loader"; - -const hiddenColumns = [ - "id", - "season.id", - "company.id", - "recruiter.id", - "recruiter.user.id", -]; - -const JobPage = () => { - const columns = generateColumns(recruitmentDTO); - const [loading, setLoading] = useState(true); - const [allJobs, setAllJobs] = useState(); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - useEffect(() => { - const getData = async () => { - const data = await fetchAllJobs(); - const newData = data.map((d: any) => ({ - ...d, - active: d.active ? "Active" : "Inactive", - })); - setAllJobs(newData); - setLoading(false); - }; - getData(); - }, []); - - return ( -
-

Jobs

-
- {loading && ( -
- -
- )} - {allJobs && ( -
- )} - - - ); -}; - -export default JobPage; +"use client"; +import { fetchAllJobs } from "@/helpers/api"; +import generateColumns from "@/components/NewTableComponent/ColumnMapping"; +import type { RecruitmentDTO } from "@/dto/JobDto"; +import { recruitmentDTO } from "@/dto/JobDto"; +import { createMRTColumnHelper } from "material-react-table"; +import Table from "@/components/NewTableComponent/Table"; +import { useEffect, useState } from "react"; +import Loader from "@/components/Loader/loader"; + +const hiddenColumns = [ + "id", + "season.id", + "company.id", + "recruiter.id", + "recruiter.user.id", +]; + +const JobPage = () => { + const columns = generateColumns(recruitmentDTO); + const [loading, setLoading] = useState(true); + const [allJobs, setAllJobs] = useState(); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + useEffect(() => { + const getData = async () => { + const data = await fetchAllJobs(); + const newData = data.map((d: any) => ({ + ...d, + active: d.active ? "Active" : "Inactive", + })); + setAllJobs(newData); + setLoading(false); + }; + getData(); + }, []); + + return ( +
+

Jobs

+
+ {loading && ( +
+ +
+ )} + {allJobs && ( +
+ )} + + + ); +}; + +export default JobPage; diff --git a/src/app/(routes)/admin/layout.tsx b/src/app/(routes)/admin/layout.tsx index 70e10113..8ca00736 100644 --- a/src/app/(routes)/admin/layout.tsx +++ b/src/app/(routes)/admin/layout.tsx @@ -1,14 +1,14 @@ -//layout for admin routes, this is the parent component for all admin routes -//tailwindcss is used for styling, nextjs is used for routing, framer-motion is used for animations and typescript is used for type checking -// import { motion } from "framer-motion"; -import Link from "next/link"; - -interface Props { - children: React.ReactNode; -} - -const AdminLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminLayout; +//layout for admin routes, this is the parent component for all admin routes +//tailwindcss is used for styling, nextjs is used for routing, framer-motion is used for animations and typescript is used for type checking +// import { motion } from "framer-motion"; +import Link from "next/link"; + +interface Props { + children: React.ReactNode; +} + +const AdminLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminLayout; diff --git a/src/app/(routes)/admin/profile/page.tsx b/src/app/(routes)/admin/profile/page.tsx index b6dbbdeb..ce2069d0 100644 --- a/src/app/(routes)/admin/profile/page.tsx +++ b/src/app/(routes)/admin/profile/page.tsx @@ -1,12 +1,12 @@ -import React from "react"; -import AdminProfile from "@/components/Admin/Profile"; - -const ProfilePage = () => { - return ( -
- -
- ); -}; - -export default ProfilePage; +import React from "react"; +import AdminProfile from "@/components/Admin/Profile"; + +const ProfilePage = () => { + return ( +
+ +
+ ); +}; + +export default ProfilePage; diff --git a/src/app/(routes)/admin/recruiters/layout.tsx b/src/app/(routes)/admin/recruiters/layout.tsx index 4c8fb74c..1d0c22e3 100644 --- a/src/app/(routes)/admin/recruiters/layout.tsx +++ b/src/app/(routes)/admin/recruiters/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminRecruiterLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminRecruiterLayout; +interface Props { + children: React.ReactNode; +} + +const AdminRecruiterLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminRecruiterLayout; diff --git a/src/app/(routes)/admin/recruiters/loading.tsx b/src/app/(routes)/admin/recruiters/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/recruiters/loading.tsx +++ b/src/app/(routes)/admin/recruiters/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/recruiters/page.tsx b/src/app/(routes)/admin/recruiters/page.tsx index 3e93122a..a726fe04 100644 --- a/src/app/(routes)/admin/recruiters/page.tsx +++ b/src/app/(routes)/admin/recruiters/page.tsx @@ -1,46 +1,46 @@ -"use client"; -import { fetchRecruiterData } from "@/helpers/api"; -import Table from "@/components/NewTableComponent/Table"; -import generateColumns from "@/components/NewTableComponent/ColumnMapping"; -import { RecruiterDTO, recruiterdto } from "@/dto/RecruiterDto"; -import { useEffect, useState } from "react"; -import toast from "react-hot-toast"; - -const hiddenColumns = ["id", "user.id", "company.id"]; - -const StudentPage = async () => { - const columns = generateColumns(recruiterdto); - const [AllRecruiters, setRecruiters] = useState([]); - useEffect(() => { - const fetchRecruiters = async () => { - try { - const data = await fetchRecruiterData(); - setRecruiters(data); - } catch (error) { - toast.error("Error fetching data:"); - } - }; - - fetchRecruiters(); - }, []); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - return ( -
-

Recruiters

-
- {AllRecruiters && ( -
- )} - - - ); -}; - -export default StudentPage; +"use client"; +import { fetchRecruiterData } from "@/helpers/api"; +import Table from "@/components/NewTableComponent/Table"; +import generateColumns from "@/components/NewTableComponent/ColumnMapping"; +import { RecruiterDTO, recruiterdto } from "@/dto/RecruiterDto"; +import { useEffect, useState } from "react"; +import toast from "react-hot-toast"; + +const hiddenColumns = ["id", "user.id", "company.id"]; + +const StudentPage = async () => { + const columns = generateColumns(recruiterdto); + const [AllRecruiters, setRecruiters] = useState([]); + useEffect(() => { + const fetchRecruiters = async () => { + try { + const data = await fetchRecruiterData(); + setRecruiters(data); + } catch (error) { + toast.error("Error fetching data:"); + } + }; + + fetchRecruiters(); + }, []); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + return ( +
+

Recruiters

+
+ {AllRecruiters && ( +
+ )} + + + ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/admin/resumes/layout.tsx b/src/app/(routes)/admin/resumes/layout.tsx index b4135c73..9a3afc24 100644 --- a/src/app/(routes)/admin/resumes/layout.tsx +++ b/src/app/(routes)/admin/resumes/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminResumeLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminResumeLayout; +interface Props { + children: React.ReactNode; +} + +const AdminResumeLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminResumeLayout; diff --git a/src/app/(routes)/admin/resumes/loading.tsx b/src/app/(routes)/admin/resumes/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/resumes/loading.tsx +++ b/src/app/(routes)/admin/resumes/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/resumes/page.tsx b/src/app/(routes)/admin/resumes/page.tsx index 135481d3..20e1a23b 100644 --- a/src/app/(routes)/admin/resumes/page.tsx +++ b/src/app/(routes)/admin/resumes/page.tsx @@ -1,92 +1,92 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { fetchResumes, getResumeFile, patchResumeVerify } from "@/helpers/api"; -import generateColumns from "@/components/NewTableComponent/ColumnMapping"; -import Table from "@/components/NewTableComponent/Table"; -import { resumeDto, Resume, ResumeTableData } from "@/dto/ResumeDto"; -import Link from "next/link"; -import VerifiedIcon from "@mui/icons-material/Verified"; -import PendingOutlinedIcon from "@mui/icons-material/PendingOutlined"; -import { Button } from "@/components/ui/button"; -import toast, { Toaster } from "react-hot-toast"; - -const hiddenColumns = [ - "student.id", - "id", - "student.user.id", - "student.program.id", -]; - -const Resumes = () => { - const [allresumes, setAllResumes] = useState(); - const newResumeDto = [{ update: "string", ...resumeDto[0] }]; - const columns = generateColumns(newResumeDto); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - const updateVerification = (id: string, resumes: ResumeTableData[]) => { - patchResumeVerify([{ id: id, verified: true }]); - const updatedResumes: ResumeTableData[] = resumes.map((resume) => - resume.id == id ? { ...resume, verified: true } : resume, - ); - setData(updatedResumes); - }; - - const setData = (data: ResumeTableData[]) => { - const newData = data.map((resume) => ({ - ...resume, - filepath: ( - - ), - verified: ( -
- {resume.verified ? : } -
- ), - update: resume.verified ? ( - "Verified" - ) : ( - - ), - })); - setAllResumes((prevData) => newData); - }; - - useEffect(() => { - const fetchData = async () => { - const data: ResumeTableData[] = await fetchResumes(); - if (!data) { - toast.error("Some error Occured"); - return; - } - setData(data); - }; - fetchData(); - }, []); - - return ( -
-

Resumes

-
- {allresumes && ( -
- )} - - - ); -}; - -export default Resumes; +"use client"; +import React, { useEffect, useState } from "react"; +import { fetchResumes, getResumeFile, patchResumeVerify } from "@/helpers/api"; +import generateColumns from "@/components/NewTableComponent/ColumnMapping"; +import Table from "@/components/NewTableComponent/Table"; +import { resumeDto, Resume, ResumeTableData } from "@/dto/ResumeDto"; +import Link from "next/link"; +import VerifiedIcon from "@mui/icons-material/Verified"; +import PendingOutlinedIcon from "@mui/icons-material/PendingOutlined"; +import { Button } from "@/components/ui/button"; +import toast, { Toaster } from "react-hot-toast"; + +const hiddenColumns = [ + "student.id", + "id", + "student.user.id", + "student.program.id", +]; + +const Resumes = () => { + const [allresumes, setAllResumes] = useState(); + const newResumeDto = [{ update: "string", ...resumeDto[0] }]; + const columns = generateColumns(newResumeDto); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + const updateVerification = (id: string, resumes: ResumeTableData[]) => { + patchResumeVerify([{ id: id, verified: true }]); + const updatedResumes: ResumeTableData[] = resumes.map((resume) => + resume.id == id ? { ...resume, verified: true } : resume, + ); + setData(updatedResumes); + }; + + const setData = (data: ResumeTableData[]) => { + const newData = data.map((resume) => ({ + ...resume, + filepath: ( + + ), + verified: ( +
+ {resume.verified ? : } +
+ ), + update: resume.verified ? ( + "Verified" + ) : ( + + ), + })); + setAllResumes((prevData) => newData); + }; + + useEffect(() => { + const fetchData = async () => { + const data: ResumeTableData[] = await fetchResumes(); + if (!data) { + toast.error("Some error Occured"); + return; + } + setData(data); + }; + fetchData(); + }, []); + + return ( +
+

Resumes

+
+ {allresumes && ( +
+ )} + + + ); +}; + +export default Resumes; diff --git a/src/app/(routes)/admin/seasons/layout.tsx b/src/app/(routes)/admin/seasons/layout.tsx index d1431a56..1a80df98 100644 --- a/src/app/(routes)/admin/seasons/layout.tsx +++ b/src/app/(routes)/admin/seasons/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const SeasonsLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default SeasonsLayout; +interface Props { + children: React.ReactNode; +} + +const SeasonsLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default SeasonsLayout; diff --git a/src/app/(routes)/admin/seasons/loading.tsx b/src/app/(routes)/admin/seasons/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/seasons/loading.tsx +++ b/src/app/(routes)/admin/seasons/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/seasons/page.tsx b/src/app/(routes)/admin/seasons/page.tsx index 014ec5d3..68ff20a8 100644 --- a/src/app/(routes)/admin/seasons/page.tsx +++ b/src/app/(routes)/admin/seasons/page.tsx @@ -1,65 +1,65 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import { AllSeasons } from "@/components/Admin/AllSeasons"; -import { fetchAllSeasons } from "@/helpers/api"; -import { SeasonFC } from "@/helpers/season/types"; -import { Button } from "@/components/ui/button"; -import { AddSeason } from "@/components/Admin/AllSeasons"; -import Loader from "@/components/Loader/loader"; -import toast from "react-hot-toast"; - -const SeasonsPage = () => { - const [seasons, setData] = useState<[SeasonFC]>(null); - const [loading, setLoading] = useState(true); - const [addSeasonForm, setAddSeasonForm] = useState(false); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await fetchAllSeasons(); - setData(jsonData); - } catch (error) { - toast.error("Some error occured"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, []); - return ( -
-

- Seasons -

- {addSeasonForm && ( - - )} -
- -
- {loading && ( -
- -
- )} - {seasons && ( -
- -
- )} -
- ); -}; - -export default SeasonsPage; +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { AllSeasons } from "@/components/Admin/AllSeasons"; +import { fetchAllSeasons } from "@/helpers/api"; +import { SeasonFC } from "@/helpers/season/types"; +import { Button } from "@/components/ui/button"; +import { AddSeason } from "@/components/Admin/AllSeasons"; +import Loader from "@/components/Loader/loader"; +import toast from "react-hot-toast"; + +const SeasonsPage = () => { + const [seasons, setData] = useState<[SeasonFC]>(null); + const [loading, setLoading] = useState(true); + const [addSeasonForm, setAddSeasonForm] = useState(false); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await fetchAllSeasons(); + setData(jsonData); + } catch (error) { + toast.error("Some error occured"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, []); + return ( +
+

+ Seasons +

+ {addSeasonForm && ( + + )} +
+ +
+ {loading && ( +
+ +
+ )} + {seasons && ( +
+ +
+ )} +
+ ); +}; + +export default SeasonsPage; diff --git a/src/app/(routes)/admin/students/[...filter]/page.tsx b/src/app/(routes)/admin/students/[...filter]/page.tsx index 287cc55a..a7868186 100644 --- a/src/app/(routes)/admin/students/[...filter]/page.tsx +++ b/src/app/(routes)/admin/students/[...filter]/page.tsx @@ -1,60 +1,60 @@ -"use client"; -import { fetchStudentData } from "@/helpers/api"; -import TableComponent from "@/components/TableComponent/TableComponent"; -import generateColumns from "@/components/TableComponent/ColumnMapping"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; - -const dto = [ - { - id: "string", - userId: "string", - programId: "string", - rollNo: "number", - category: "string", - gender: "MALE", - cpi: "number", - user: { name: "string", email: "string", contact: "string" }, - program: { course: "string", branch: "string", year: "number" }, - }, -]; - -const dynamicColumns = generateColumns(dto[0]); - -const StudentPage = ({ params }: any) => { - const [students, setStudents] = useState([]); - - useEffect(() => { - const fetchData = async () => { - // Decode the URL - - // Extract query parameters from the URL - const decodedParams = decodeURIComponent(params.filter[0]); - const AllStudents = await fetchStudentData(decodedParams); - setStudents(AllStudents); - }; - - fetchData(); - }, [params?.filter[0]]); - - return ( -
-

- Students Filter -

-
- {students.length > 0 && ( - - )} -
-
- ); -}; - -export default StudentPage; +"use client"; +import { fetchStudentData } from "@/helpers/api"; +import TableComponent from "@/components/TableComponent/TableComponent"; +import generateColumns from "@/components/TableComponent/ColumnMapping"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + +const dto = [ + { + id: "string", + userId: "string", + programId: "string", + rollNo: "number", + category: "string", + gender: "MALE", + cpi: "number", + user: { name: "string", email: "string", contact: "string" }, + program: { course: "string", branch: "string", year: "number" }, + }, +]; + +const dynamicColumns = generateColumns(dto[0]); + +const StudentPage = ({ params }: any) => { + const [students, setStudents] = useState([]); + + useEffect(() => { + const fetchData = async () => { + // Decode the URL + + // Extract query parameters from the URL + const decodedParams = decodeURIComponent(params.filter[0]); + const AllStudents = await fetchStudentData(decodedParams); + setStudents(AllStudents); + }; + + fetchData(); + }, [params?.filter[0]]); + + return ( +
+

+ Students Filter +

+
+ {students.length > 0 && ( + + )} +
+
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/admin/students/layout.tsx b/src/app/(routes)/admin/students/layout.tsx index 69a0fb7d..221ab18d 100644 --- a/src/app/(routes)/admin/students/layout.tsx +++ b/src/app/(routes)/admin/students/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const AdminStudentLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default AdminStudentLayout; +interface Props { + children: React.ReactNode; +} + +const AdminStudentLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default AdminStudentLayout; diff --git a/src/app/(routes)/admin/students/loading.tsx b/src/app/(routes)/admin/students/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/admin/students/loading.tsx +++ b/src/app/(routes)/admin/students/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/admin/students/page.tsx b/src/app/(routes)/admin/students/page.tsx index 3987632f..2b0cfcf3 100644 --- a/src/app/(routes)/admin/students/page.tsx +++ b/src/app/(routes)/admin/students/page.tsx @@ -1,40 +1,40 @@ -"use client"; -import { useState, useEffect } from "react"; -import { fetchStudentData } from "@/helpers/api"; -import Table from "@/components/NewTableComponent/Table"; -import type { DTO } from "@/dto/StudentDto"; -import generateColumns from "@/components/NewTableComponent/ColumnMapping"; -import { jsondto } from "@/dto/StudentDto"; - -const hiddenColumns = ["userId", "programId", "id"]; - -const StudentPage = () => { - const [students, setStudents] = useState([]); - const columns = generateColumns(jsondto); - - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - useEffect(() => { - const fetchData = async () => { - const data = await fetchStudentData(); - setStudents(data); - }; - - fetchData(); - }, []); - - return ( -
-

Students

-
- {students.length > 0 && ( -
- )} - - - ); -}; - -export default StudentPage; +"use client"; +import { useState, useEffect } from "react"; +import { fetchStudentData } from "@/helpers/api"; +import Table from "@/components/NewTableComponent/Table"; +import type { DTO } from "@/dto/StudentDto"; +import generateColumns from "@/components/NewTableComponent/ColumnMapping"; +import { jsondto } from "@/dto/StudentDto"; + +const hiddenColumns = ["userId", "programId", "id"]; + +const StudentPage = () => { + const [students, setStudents] = useState([]); + const columns = generateColumns(jsondto); + + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + useEffect(() => { + const fetchData = async () => { + const data = await fetchStudentData(); + setStudents(data); + }; + + fetchData(); + }, []); + + return ( +
+

Students

+
+ {students.length > 0 && ( +
+ )} + + + ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/faculty/layout.tsx b/src/app/(routes)/faculty/layout.tsx index 718257b2..97f87397 100644 --- a/src/app/(routes)/faculty/layout.tsx +++ b/src/app/(routes)/faculty/layout.tsx @@ -1,11 +1,11 @@ -import Link from "next/link"; - -interface Props { - children: React.ReactNode; -} - -const FacultyLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default FacultyLayout; +import Link from "next/link"; + +interface Props { + children: React.ReactNode; +} + +const FacultyLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default FacultyLayout; diff --git a/src/app/(routes)/faculty/loading.tsx b/src/app/(routes)/faculty/loading.tsx index c7f5b8c1..e7627aa1 100644 --- a/src/app/(routes)/faculty/loading.tsx +++ b/src/app/(routes)/faculty/loading.tsx @@ -1,29 +1,29 @@ -"use client"; - -import React, { Component } from "react"; -import { CircularProgress } from "@mui/material"; -import Loader from "@/components/Loader/loader"; - -class Loading extends Component { - render() { - const { error }: any = this.props; - - // If an error prop is provided and it's true, display the error message - if (error) { - return ( -
- Error: Something went wrong. -
- ); - } - - // Otherwise, display the Material-UI CircularProgress component - return ( -
- -
- ); - } -} - -export default Loading; +"use client"; + +import React, { Component } from "react"; +import { CircularProgress } from "@mui/material"; +import Loader from "@/components/Loader/loader"; + +class Loading extends Component { + render() { + const { error }: any = this.props; + + // If an error prop is provided and it's true, display the error message + if (error) { + return ( +
+ Error: Something went wrong. +
+ ); + } + + // Otherwise, display the Material-UI CircularProgress component + return ( +
+ +
+ ); + } +} + +export default Loading; diff --git a/src/app/(routes)/faculty/page.tsx b/src/app/(routes)/faculty/page.tsx index cee229d4..c3bbd5ab 100644 --- a/src/app/(routes)/faculty/page.tsx +++ b/src/app/(routes)/faculty/page.tsx @@ -1,73 +1,73 @@ -"use client"; -import { fetchApprovals } from "@/helpers/faculty/api"; -import TableComponent from "@/components/TableComponent/TableComponent"; -import generateColumns from "@/components/TableComponent/ColumnMapping"; -import { useState, useEffect } from "react"; -import Loader from "@/components/Loader/loader"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import toast from "react-hot-toast"; - -const dto = [ - { - status: "string", - remarks: "string", - salary: { - salaryPeriod: "string", - totalCTC: "number", - job: { - role: "string", - company: { - name: "string", - }, - season: { - year: "string", - type: "string", - }, - }, - }, - }, -]; - -const dynamicColumns = generateColumns(dto); - -const FacultyPage = () => { - const [data, setData] = useState(null); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await fetchApprovals(undefined); - setData(jsonData); - } catch (error) { - toast.error("Error fetching data:", error); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, []); - return ( -
-

Approvals

-
- {loading && ( -
- -
- )} - {data && ( - - )} -
-
- ); -}; - -export default FacultyPage; +"use client"; +import { fetchApprovals } from "@/helpers/faculty/api"; +import TableComponent from "@/components/TableComponent/TableComponent"; +import generateColumns from "@/components/TableComponent/ColumnMapping"; +import { useState, useEffect } from "react"; +import Loader from "@/components/Loader/loader"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import toast from "react-hot-toast"; + +const dto = [ + { + status: "string", + remarks: "string", + salary: { + salaryPeriod: "string", + totalCTC: "number", + job: { + role: "string", + company: { + name: "string", + }, + season: { + year: "string", + type: "string", + }, + }, + }, + }, +]; + +const dynamicColumns = generateColumns(dto); + +const FacultyPage = () => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await fetchApprovals(undefined); + setData(jsonData); + } catch (error) { + toast.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, []); + return ( +
+

Approvals

+
+ {loading && ( +
+ +
+ )} + {data && ( + + )} +
+
+ ); +}; + +export default FacultyPage; diff --git a/src/app/(routes)/faculty/profile/page.tsx b/src/app/(routes)/faculty/profile/page.tsx index e28742df..679dfc50 100644 --- a/src/app/(routes)/faculty/profile/page.tsx +++ b/src/app/(routes)/faculty/profile/page.tsx @@ -1,17 +1,17 @@ -"use client"; - -import React, { useEffect, useState } from "react"; -import FacultyProfile from "@/components/Faculty/Profile"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import { ProfileFC } from "@/helpers/faculty/types"; -import Loader from "@/components/Loader/loader"; - -const Profile = ({ params }: { params: { facultyId: string } }) => { - return ( -
- -
- ); -}; - -export default Profile; +"use client"; + +import React, { useEffect, useState } from "react"; +import FacultyProfile from "@/components/Faculty/Profile"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import { ProfileFC } from "@/helpers/faculty/types"; +import Loader from "@/components/Loader/loader"; + +const Profile = ({ params }: { params: { facultyId: string } }) => { + return ( +
+ +
+ ); +}; + +export default Profile; diff --git a/src/app/(routes)/recruiter/events/[jobId]/page.tsx b/src/app/(routes)/recruiter/events/[jobId]/page.tsx index 85342da7..90a05200 100644 --- a/src/app/(routes)/recruiter/events/[jobId]/page.tsx +++ b/src/app/(routes)/recruiter/events/[jobId]/page.tsx @@ -1,47 +1,47 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import { JobDetailFC } from "@/helpers/recruiter/types"; -import { getJobDetail } from "@/helpers/recruiter/api"; -import loadingImg from "@/../public/loadingSpinner.svg"; -import { JobEvents } from "@/components/Recruiters/Events"; -import Loader from "@/components/Loader/loader"; -import toast from "react-hot-toast"; -const EventsPage = ({ params }: { params: { jobId: string } }) => { - const [job, setData] = useState(null); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await getJobDetail(params.jobId); - setData(jsonData); - } catch (error) { - toast.error("Error Fetching Data"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [params.jobId]); - return ( -
-

- Events And Applications -

- {loading && ( -
- -
- )} - {job && ( -
- -
- )} -
- ); -}; - -export default EventsPage; +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { JobDetailFC } from "@/helpers/recruiter/types"; +import { getJobDetail } from "@/helpers/recruiter/api"; +import loadingImg from "@/../public/loadingSpinner.svg"; +import { JobEvents } from "@/components/Recruiters/Events"; +import Loader from "@/components/Loader/loader"; +import toast from "react-hot-toast"; +const EventsPage = ({ params }: { params: { jobId: string } }) => { + const [job, setData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await getJobDetail(params.jobId); + setData(jsonData); + } catch (error) { + toast.error("Error Fetching Data"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [params.jobId]); + return ( +
+

+ Events And Applications +

+ {loading && ( +
+ +
+ )} + {job && ( +
+ +
+ )} +
+ ); +}; + +export default EventsPage; diff --git a/src/app/(routes)/recruiter/events/page.tsx b/src/app/(routes)/recruiter/events/page.tsx index 4259f73e..77cde4c8 100644 --- a/src/app/(routes)/recruiter/events/page.tsx +++ b/src/app/(routes)/recruiter/events/page.tsx @@ -1,89 +1,89 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import { JobsFC } from "@/helpers/recruiter/types"; -import { getJobs } from "@/helpers/recruiter/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/../public/loadingSpinner.svg"; -import { useRouter } from "next/navigation"; -import { Button } from "@/components/ui/button"; -import Loader from "@/components/Loader/loader"; -const EventPage = () => { - const [data, setData] = useState(null); - const [loading, setLoading] = useState(true); - const router = useRouter(); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await getJobs(); - setData(jsonData); - } catch (error) { - toast.error("Error Fetching Data"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, []); - return ( -
-

Events

- {loading && ( -
- -
- )} - {data && ( -
-
- - - - - - - - - - {data.map((job, index) => ( - { - router.push(`/recruiter/events/${job.id}`); - }} - className="cursor-pointer bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" - > - - - - - - ))} - -
- Role - - Active - - Current Status - - More Details -
- {job.role} - - {job.active ? "Active" : "Inactive"} - {job.currentStatus} - -
-
- )} -
- ); -}; - -export default EventPage; +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { JobsFC } from "@/helpers/recruiter/types"; +import { getJobs } from "@/helpers/recruiter/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/../public/loadingSpinner.svg"; +import { useRouter } from "next/navigation"; +import { Button } from "@/components/ui/button"; +import Loader from "@/components/Loader/loader"; +const EventPage = () => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const router = useRouter(); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await getJobs(); + setData(jsonData); + } catch (error) { + toast.error("Error Fetching Data"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, []); + return ( +
+

Events

+ {loading && ( +
+ +
+ )} + {data && ( +
+ + + + + + + + + + + {data.map((job, index) => ( + { + router.push(`/recruiter/events/${job.id}`); + }} + className="cursor-pointer bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" + > + + + + + + ))} + +
+ Role + + Active + + Current Status + + More Details +
+ {job.role} + + {job.active ? "Active" : "Inactive"} + {job.currentStatus} + +
+
+ )} +
+ ); +}; + +export default EventPage; diff --git a/src/app/(routes)/recruiter/jobs/[jobID]/page.tsx b/src/app/(routes)/recruiter/jobs/[jobID]/page.tsx index 235dca8c..c4755b61 100644 --- a/src/app/(routes)/recruiter/jobs/[jobID]/page.tsx +++ b/src/app/(routes)/recruiter/jobs/[jobID]/page.tsx @@ -1,739 +1,739 @@ -"use client"; -import React, { useState, useEffect } from "react"; -import { JobDetailFC } from "@/helpers/recruiter/types"; -import { getJobDetail } from "@/helpers/recruiter/api"; -import loadingImg from "@/../public/loadingSpinner.svg"; -import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; -import PersonIcon from "@mui/icons-material/Person"; -import { Button } from "@/components/ui/button"; -import Link from "next/link"; -import { Separator } from "@/components/ui/separator"; -import { getJafDetails } from "@/helpers/recruiter/api"; -import { JAFdetailsFC } from "@/helpers/recruiter/types"; -import { patchJobData } from "@/helpers/recruiter/api"; -import { patchSalaryData } from "@/helpers/recruiter/api"; -import { - CategorySelectList, - GenderSelectList, -} from "@/components/Recruiters/jobEdit"; -import Loader from "@/components/Loader/loader"; - -const JobDetailPage = ({ params }: { params: { jobID: string } }) => { - const [job, setData] = useState(null); - const [loading, setLoading] = useState(true); - const [editMode, setEditMode] = useState(false); - const [formData, setFormData] = useState(null); - const [jafDetails, setJafDetails] = useState(); - - useEffect(() => { - const fetchData = async () => { - try { - const [jobDetailData, jafDetailsData] = await Promise.all([ - getJobDetail(params.jobID), - getJafDetails(), - ]); - - setJafDetails((prev) => jafDetailsData); - setData(jobDetailData); - setFormData(jobDetailData); - } catch (error) { - console.error("Error fetching data:", error); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [params.jobID]); - - const handleEditClick = () => { - if (editMode) { - handleSubmit(); - } - setEditMode(!editMode); - }; - - const handleChange = (e) => { - const { name, value } = e.target; - setFormData((prev) => ({ ...prev, [name]: value })); - }; - - const handleSubmit = async () => { - const c1 = await patchJobData(job.id, formData); - if (true) { - formData.salaries.map((salary, index) => patchSalaryData(salary)); - } - setEditMode(false); - window.location.reload(); - }; - - const addNewTest = () => { - const newTest = { type: "", duration: 0 }; - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - tests: [...prev.selectionProcedure.tests, newTest], - }, - })); - }; - - const addNewInterview = () => { - const newInterview = { type: "", duration: 0 }; - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - interviews: [...prev.selectionProcedure.interviews, newInterview], - }, - })); - }; - - return ( -
-

- Job Details -

- - {loading && ( -
- -
- )} - {job && ( -
-
-
-
- Role - {editMode ? ( - - ) : ( - {job.role} - )} -
-
- Activity - {job.active ? "Active" : "Inactive"} -
-
- Current Status - {job.currentStatus} -
-
- - - - {!job.active && ( - - )} -
-
-
-
Skills
-
- {editMode ? ( - - ) : ( - job.skills - )} -
-
-
-
Location
{" "} - {editMode ? ( - - ) : ( -
{job.location}
- )} -
-
-
Offer letter release
{" "} - {editMode ? ( - - ) : ( -
{job.offerLetterReleaseDate}
- )} -
-
-
Joining Date
{" "} - {editMode ? ( - - ) : ( -
{job.joiningDate}
- )} -
-
-
Duration
{" "} - {editMode ? ( - - ) : ( -
{job.duration}
- )} -
-
-
Attachment
{" "} - {editMode ? ( - - ) : ( -
{job.attachment}
- )} -
-
-
-
-
-
- Selection Procedure -
-
-
-
Selection mode
{" "} - {editMode ? ( - - ) : ( -
{job.selectionProcedure.selectionMode}
- )} -
-
-
Shortlist from Resume
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - shortlistFromResume: e.target.checked, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.shortlistFromResume ? "YES" : "NO"} -
- )} -
-
-
Group Discussion
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - groupDiscussion: e.target.checked, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.groupDiscussion ? "YES" : "NO"} -
- )} -
-
-
Number of members
{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - requirements: { - ...prev.selectionProcedure.requirements, - numberOfMembers: e.target.value, - }, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.requirements.numberOfMembers} -
- )} -
-
-
-
-
Tests
-
    - {editMode - ? formData.selectionProcedure.tests.map((test, index) => ( -
  • - Test Type: - -
    - Test Duration: - { - const updatedTests = - formData.selectionProcedure.tests.map((t, i) => - i === index - ? { ...t, duration: Number(e.target.value) } - : t, - ); - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - tests: updatedTests, - }, - })); - }} - /> -
  • - )) - : job.selectionProcedure.tests.map((p, index) => ( -
  • - {Object.entries(p).map(([key, value]) => ( - - {key} : {value} -
    -
    - ))} -
  • - ))} -
- {editMode && ( - - )} -
- - - -
-
Interviews
-
    - {editMode - ? formData.selectionProcedure.interviews.map( - (interview, index) => ( -
  • - Interview Type: - -
    - Interview Duration: - { - const updatedInterviews = - formData.selectionProcedure.interviews.map( - (i, j) => - j === index - ? { ...i, duration: e.target.value } - : i, - ); - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - interviews: updatedInterviews, - }, - })); - }} - /> -
  • - ), - ) - : job.selectionProcedure.interviews.map((p, index) => ( -
  • - {Object.entries(p).map(([key, value]) => ( - - {key} : {value} -
    -
    - ))} -
  • - ))} -
- {editMode && ( - - )} -
-
-
-
-
- Other requirements :{" "} - {editMode ? ( - { - setFormData((prev) => ({ - ...prev, - selectionProcedure: { - ...prev.selectionProcedure, - requirements: { - ...prev.selectionProcedure.requirements, - otherRequirements: e.target.value, - }, - }, - })); - }} - /> - ) : ( -
- {job.selectionProcedure.requirements.otherRequirements} -
- )} -
-
-
-
-
-
Job Coordinators
-
- {job.jobCoordinators.map((coordinator, index) => ( -
-
- -
- {coordinator.tpcMember.student.user.name} -
-
-
- Role : - {coordinator.tpcMember.role} -
-
- Department : - {coordinator.tpcMember.student.program.department} -
-
- Email : - {coordinator.tpcMember.student.user.email} -
-
- Contact : - {coordinator.tpcMember.student.user.contact} -
-
-
- ))} -
-
-
-
Salaries
- {job.salaries.map((salary, salaryIndex) => ( -
-
-
-
Base Salary
{" "} - {editMode ? ( - { - const updatedSalaries = formData.salaries.map( - (s, i) => - i === salaryIndex - ? { ...s, baseSalary: e.target.value } - : s, - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.baseSalary}
- )} -
-
-
CTC
{" "} - {editMode ? ( - { - const updatedSalaries = formData.salaries.map( - (s, i) => - i === salaryIndex - ? { ...s, totalCTC: e.target.value } - : s, - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.totalCTC}
- )} -
-
-
Take Home Salary
{" "} - {editMode ? ( - { - const updatedSalaries = formData.salaries.map( - (s, i) => - i === salaryIndex - ? { ...s, takeHomeSalary: e.target.value } - : s, - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.takeHomeSalary}
- )} -
-
-
Gross Salary
{" "} - {editMode ? ( - { - const updatedSalaries = formData.salaries.map( - (s, i) => - i === salaryIndex - ? { ...s, grossSalary: e.target.value } - : s, - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.grossSalary}
- )} -
-
-
- Other Compensations -
{" "} - {editMode ? ( - { - const updatedSalaries = formData.salaries.map( - (s, i) => - i === salaryIndex - ? { ...s, otherCompensations: e.target.value } - : s, - ); - setFormData((prev) => ({ - ...prev, - salaries: updatedSalaries, - })); - }} - /> - ) : ( -
{salary.otherCompensations}
- )} -
-
- {/* Genders */} -
-

Genders

- {editMode ? ( - - ) : ( -
- {salary.genders?.map((gender, genderIndex) => ( -
- {editMode ? null : ( -
- {gender} -
- )} -
- ))} -
- )} -
- - {/* Categories */} -
-

Categories

- {editMode ? ( - - ) : ( -
- {salary.categories?.map((category, categoryIndex) => ( -
- {editMode ? null : ( -
- {category} -
- )} -
- ))} -
- )} -
- - -
- ))} -
-
- )} -
- ); -}; - -export default JobDetailPage; +"use client"; +import React, { useState, useEffect } from "react"; +import { JobDetailFC } from "@/helpers/recruiter/types"; +import { getJobDetail } from "@/helpers/recruiter/api"; +import loadingImg from "@/../public/loadingSpinner.svg"; +import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; +import PersonIcon from "@mui/icons-material/Person"; +import { Button } from "@/components/ui/button"; +import Link from "next/link"; +import { Separator } from "@/components/ui/separator"; +import { getJafDetails } from "@/helpers/recruiter/api"; +import { JAFdetailsFC } from "@/helpers/recruiter/types"; +import { patchJobData } from "@/helpers/recruiter/api"; +import { patchSalaryData } from "@/helpers/recruiter/api"; +import { + CategorySelectList, + GenderSelectList, +} from "@/components/Recruiters/jobEdit"; +import Loader from "@/components/Loader/loader"; + +const JobDetailPage = ({ params }: { params: { jobID: string } }) => { + const [job, setData] = useState(null); + const [loading, setLoading] = useState(true); + const [editMode, setEditMode] = useState(false); + const [formData, setFormData] = useState(null); + const [jafDetails, setJafDetails] = useState(); + + useEffect(() => { + const fetchData = async () => { + try { + const [jobDetailData, jafDetailsData] = await Promise.all([ + getJobDetail(params.jobID), + getJafDetails(), + ]); + + setJafDetails((prev) => jafDetailsData); + setData(jobDetailData); + setFormData(jobDetailData); + } catch (error) { + console.error("Error fetching data:", error); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [params.jobID]); + + const handleEditClick = () => { + if (editMode) { + handleSubmit(); + } + setEditMode(!editMode); + }; + + const handleChange = (e) => { + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); + }; + + const handleSubmit = async () => { + const c1 = await patchJobData(job.id, formData); + if (true) { + formData.salaries.map((salary, index) => patchSalaryData(salary)); + } + setEditMode(false); + window.location.reload(); + }; + + const addNewTest = () => { + const newTest = { type: "", duration: 0 }; + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + tests: [...prev.selectionProcedure.tests, newTest], + }, + })); + }; + + const addNewInterview = () => { + const newInterview = { type: "", duration: 0 }; + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + interviews: [...prev.selectionProcedure.interviews, newInterview], + }, + })); + }; + + return ( +
+

+ Job Details +

+ + {loading && ( +
+ +
+ )} + {job && ( +
+
+
+
+ Role + {editMode ? ( + + ) : ( + {job.role} + )} +
+
+ Activity + {job.active ? "Active" : "Inactive"} +
+
+ Current Status + {job.currentStatus} +
+
+ + + + {!job.active && ( + + )} +
+
+
+
Skills
+
+ {editMode ? ( + + ) : ( + job.skills + )} +
+
+
+
Location
{" "} + {editMode ? ( + + ) : ( +
{job.location}
+ )} +
+
+
Offer letter release
{" "} + {editMode ? ( + + ) : ( +
{job.offerLetterReleaseDate}
+ )} +
+
+
Joining Date
{" "} + {editMode ? ( + + ) : ( +
{job.joiningDate}
+ )} +
+
+
Duration
{" "} + {editMode ? ( + + ) : ( +
{job.duration}
+ )} +
+
+
Attachment
{" "} + {editMode ? ( + + ) : ( +
{job.attachment}
+ )} +
+
+
+
+
+
+ Selection Procedure +
+
+
+
Selection mode
{" "} + {editMode ? ( + + ) : ( +
{job.selectionProcedure.selectionMode}
+ )} +
+
+
Shortlist from Resume
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + shortlistFromResume: e.target.checked, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.shortlistFromResume ? "YES" : "NO"} +
+ )} +
+
+
Group Discussion
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + groupDiscussion: e.target.checked, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.groupDiscussion ? "YES" : "NO"} +
+ )} +
+
+
Number of members
{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + requirements: { + ...prev.selectionProcedure.requirements, + numberOfMembers: e.target.value, + }, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.requirements.numberOfMembers} +
+ )} +
+
+
+
+
Tests
+
    + {editMode + ? formData.selectionProcedure.tests.map((test, index) => ( +
  • + Test Type: + +
    + Test Duration: + { + const updatedTests = + formData.selectionProcedure.tests.map((t, i) => + i === index + ? { ...t, duration: Number(e.target.value) } + : t, + ); + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + tests: updatedTests, + }, + })); + }} + /> +
  • + )) + : job.selectionProcedure.tests.map((p, index) => ( +
  • + {Object.entries(p).map(([key, value]) => ( + + {key} : {value} +
    +
    + ))} +
  • + ))} +
+ {editMode && ( + + )} +
+ + + +
+
Interviews
+
    + {editMode + ? formData.selectionProcedure.interviews.map( + (interview, index) => ( +
  • + Interview Type: + +
    + Interview Duration: + { + const updatedInterviews = + formData.selectionProcedure.interviews.map( + (i, j) => + j === index + ? { ...i, duration: e.target.value } + : i, + ); + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + interviews: updatedInterviews, + }, + })); + }} + /> +
  • + ), + ) + : job.selectionProcedure.interviews.map((p, index) => ( +
  • + {Object.entries(p).map(([key, value]) => ( + + {key} : {value} +
    +
    + ))} +
  • + ))} +
+ {editMode && ( + + )} +
+
+
+
+
+ Other requirements :{" "} + {editMode ? ( + { + setFormData((prev) => ({ + ...prev, + selectionProcedure: { + ...prev.selectionProcedure, + requirements: { + ...prev.selectionProcedure.requirements, + otherRequirements: e.target.value, + }, + }, + })); + }} + /> + ) : ( +
+ {job.selectionProcedure.requirements.otherRequirements} +
+ )} +
+
+
+
+
+
Job Coordinators
+
+ {job.jobCoordinators.map((coordinator, index) => ( +
+
+ +
+ {coordinator.tpcMember.student.user.name} +
+
+
+ Role : + {coordinator.tpcMember.role} +
+
+ Department : + {coordinator.tpcMember.student.program.department} +
+
+ Email : + {coordinator.tpcMember.student.user.email} +
+
+ Contact : + {coordinator.tpcMember.student.user.contact} +
+
+
+ ))} +
+
+
+
Salaries
+ {job.salaries.map((salary, salaryIndex) => ( +
+
+
+
Base Salary
{" "} + {editMode ? ( + { + const updatedSalaries = formData.salaries.map( + (s, i) => + i === salaryIndex + ? { ...s, baseSalary: e.target.value } + : s, + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.baseSalary}
+ )} +
+
+
CTC
{" "} + {editMode ? ( + { + const updatedSalaries = formData.salaries.map( + (s, i) => + i === salaryIndex + ? { ...s, totalCTC: e.target.value } + : s, + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.totalCTC}
+ )} +
+
+
Take Home Salary
{" "} + {editMode ? ( + { + const updatedSalaries = formData.salaries.map( + (s, i) => + i === salaryIndex + ? { ...s, takeHomeSalary: e.target.value } + : s, + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.takeHomeSalary}
+ )} +
+
+
Gross Salary
{" "} + {editMode ? ( + { + const updatedSalaries = formData.salaries.map( + (s, i) => + i === salaryIndex + ? { ...s, grossSalary: e.target.value } + : s, + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.grossSalary}
+ )} +
+
+
+ Other Compensations +
{" "} + {editMode ? ( + { + const updatedSalaries = formData.salaries.map( + (s, i) => + i === salaryIndex + ? { ...s, otherCompensations: e.target.value } + : s, + ); + setFormData((prev) => ({ + ...prev, + salaries: updatedSalaries, + })); + }} + /> + ) : ( +
{salary.otherCompensations}
+ )} +
+
+ {/* Genders */} +
+

Genders

+ {editMode ? ( + + ) : ( +
+ {salary.genders?.map((gender, genderIndex) => ( +
+ {editMode ? null : ( +
+ {gender} +
+ )} +
+ ))} +
+ )} +
+ + {/* Categories */} +
+

Categories

+ {editMode ? ( + + ) : ( +
+ {salary.categories?.map((category, categoryIndex) => ( +
+ {editMode ? null : ( +
+ {category} +
+ )} +
+ ))} +
+ )} +
+ + +
+ ))} +
+
+ )} +
+ ); +}; + +export default JobDetailPage; diff --git a/src/app/(routes)/recruiter/jobs/page.tsx b/src/app/(routes)/recruiter/jobs/page.tsx index 4a40e563..c9cbe1fd 100644 --- a/src/app/(routes)/recruiter/jobs/page.tsx +++ b/src/app/(routes)/recruiter/jobs/page.tsx @@ -1,94 +1,94 @@ -"use client"; -import React from "react"; -import { getJobs } from "@/helpers/recruiter/api"; -import { JobsFC } from "@/helpers/recruiter/types"; -import { useState, useEffect } from "react"; -import loadingImg from "@/../public/loadingSpinner.svg"; -import { useRouter } from "next/navigation"; -import Loader from "@/components/Loader/loader"; -import toast from "react-hot-toast"; -const JobPage = () => { - const [data, setData] = useState(null); - const [loading, setLoading] = useState(true); - const router = useRouter(); - - useEffect(() => { - const fetchData = async () => { - try { - const jsonData = await getJobs(); - setData(jsonData); - } catch (error) { - toast.error("Error Fetching Data"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, []); - return ( -
-

All Jobs

- {loading && ( -
- -
- )} - {data && ( -
- - - - - - - - - - - - - {data.map((job, index) => ( - { - router.push(`/recruiter/jobs/${job.id}`); - }} - className="cursor-pointer bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" - > - - - - - - - - ))} - -
- Role - - Active - - Current Status - - Season Year - - Season Type - - Company Name -
- {job.role} - - {job.active ? "Active" : "Inactive"} - {job.currentStatus}{job.season.type}{job.season.year}{job.company.name}
-
- )} -
- ); -}; - -export default JobPage; +"use client"; +import React from "react"; +import { getJobs } from "@/helpers/recruiter/api"; +import { JobsFC } from "@/helpers/recruiter/types"; +import { useState, useEffect } from "react"; +import loadingImg from "@/../public/loadingSpinner.svg"; +import { useRouter } from "next/navigation"; +import Loader from "@/components/Loader/loader"; +import toast from "react-hot-toast"; +const JobPage = () => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + const router = useRouter(); + + useEffect(() => { + const fetchData = async () => { + try { + const jsonData = await getJobs(); + setData(jsonData); + } catch (error) { + toast.error("Error Fetching Data"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, []); + return ( +
+

All Jobs

+ {loading && ( +
+ +
+ )} + {data && ( +
+ + + + + + + + + + + + + {data.map((job, index) => ( + { + router.push(`/recruiter/jobs/${job.id}`); + }} + className="cursor-pointer bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" + > + + + + + + + + ))} + +
+ Role + + Active + + Current Status + + Season Year + + Season Type + + Company Name +
+ {job.role} + + {job.active ? "Active" : "Inactive"} + {job.currentStatus}{job.season.type}{job.season.year}{job.company.name}
+
+ )} +
+ ); +}; + +export default JobPage; diff --git a/src/app/(routes)/recruiter/layout.tsx b/src/app/(routes)/recruiter/layout.tsx index f5f27331..7ad919a8 100644 --- a/src/app/(routes)/recruiter/layout.tsx +++ b/src/app/(routes)/recruiter/layout.tsx @@ -1,9 +1,9 @@ -interface Props { - children: React.ReactNode; -} - -const RecruiterLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default RecruiterLayout; +interface Props { + children: React.ReactNode; +} + +const RecruiterLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default RecruiterLayout; diff --git a/src/app/(routes)/recruiter/page.tsx b/src/app/(routes)/recruiter/page.tsx index f134dc7d..083a618d 100644 --- a/src/app/(routes)/recruiter/page.tsx +++ b/src/app/(routes)/recruiter/page.tsx @@ -1,14 +1,14 @@ -"use client"; - -import React from "react"; -import RecruiterProfile from "@/components/Recruiters/profile"; - -const Profile = () => { - return ( -
- -
- ); -}; - -export default Profile; +"use client"; + +import React from "react"; +import RecruiterProfile from "@/components/Recruiters/profile"; + +const Profile = () => { + return ( +
+ +
+ ); +}; + +export default Profile; diff --git a/src/app/(routes)/recruiter/profile/page.tsx b/src/app/(routes)/recruiter/profile/page.tsx index cbe2f1a3..f760a9e1 100644 --- a/src/app/(routes)/recruiter/profile/page.tsx +++ b/src/app/(routes)/recruiter/profile/page.tsx @@ -1,13 +1,13 @@ -"use client"; - -import React from "react"; -import RecruiterProfile from "@/components/Recruiters/profile"; -const Profile = () => { - return ( -
- -
- ); -}; - -export default Profile; +"use client"; + +import React from "react"; +import RecruiterProfile from "@/components/Recruiters/profile"; +const Profile = () => { + return ( +
+ +
+ ); +}; + +export default Profile; diff --git a/src/app/(routes)/student/interviewExperiences/page.tsx b/src/app/(routes)/student/interviewExperiences/page.tsx index eb7124a7..d4f4d9c6 100644 --- a/src/app/(routes)/student/interviewExperiences/page.tsx +++ b/src/app/(routes)/student/interviewExperiences/page.tsx @@ -1,97 +1,97 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { - Table, - TableHeader, - TableBody, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { Separator } from "@/components/ui/separator"; -import { InterviewExperience } from "@/helpers/student/types"; -import { - GetInterviewExpiriences, - OpenInterviewExpirience, -} from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; -const InterviewExpiriencePage = () => { - const [interviewExpirienceData, setInterviewExpirienceData] = useState< - InterviewExperience[] - >([]); - const [loading, setLoading] = useState(true); - - const fetchInterviewExpiriences = async () => { - try { - const data = await GetInterviewExpiriences(); - setInterviewExpirienceData(data); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - const handleOpenInterviewExpirience = async (filename: string) => { - OpenInterviewExpirience(filename); - }; - - useEffect(() => { - if (interviewExpirienceData.length == 0) { - fetchInterviewExpiriences(); - } - }); - - return ( - <> -
-
Interview Expiriences
-
- -
- {loading && ( -
- -
- )} - {interviewExpirienceData.length > 0 && ( - - - - Sr. - Company - Student - Season - - - - {interviewExpirienceData.map((item, index) => ( - - {index + 1} - {item.company.name} - -
- handleOpenInterviewExpirience(item.filename) - } - > - {item.studentName} -
-
- - {item.season.type} {item.season.year} - -
- ))} -
-
- )} -
- - ); -}; - -export default InterviewExpiriencePage; +"use client"; +import React, { useEffect, useState } from "react"; +import { + Table, + TableHeader, + TableBody, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { Separator } from "@/components/ui/separator"; +import { InterviewExperience } from "@/helpers/student/types"; +import { + GetInterviewExpiriences, + OpenInterviewExpirience, +} from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; +const InterviewExpiriencePage = () => { + const [interviewExpirienceData, setInterviewExpirienceData] = useState< + InterviewExperience[] + >([]); + const [loading, setLoading] = useState(true); + + const fetchInterviewExpiriences = async () => { + try { + const data = await GetInterviewExpiriences(); + setInterviewExpirienceData(data); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + const handleOpenInterviewExpirience = async (filename: string) => { + OpenInterviewExpirience(filename); + }; + + useEffect(() => { + if (interviewExpirienceData.length == 0) { + fetchInterviewExpiriences(); + } + }); + + return ( + <> +
+
Interview Expiriences
+
+ +
+ {loading && ( +
+ +
+ )} + {interviewExpirienceData.length > 0 && ( + + + + Sr. + Company + Student + Season + + + + {interviewExpirienceData.map((item, index) => ( + + {index + 1} + {item.company.name} + +
+ handleOpenInterviewExpirience(item.filename) + } + > + {item.studentName} +
+
+ + {item.season.type} {item.season.year} + +
+ ))} +
+
+ )} +
+ + ); +}; + +export default InterviewExpiriencePage; diff --git a/src/app/(routes)/student/job/[jobId]/page.tsx b/src/app/(routes)/student/job/[jobId]/page.tsx index e63344a3..4c4efb10 100644 --- a/src/app/(routes)/student/job/[jobId]/page.tsx +++ b/src/app/(routes)/student/job/[jobId]/page.tsx @@ -1,361 +1,361 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { Separator } from "@/components/ui/separator"; -import { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { Button } from "@/components/ui/button"; -import HorizontalTimeline from "@/components/HorizontalTimeline"; -import { - Job, - CustomEvent, - EventData, - CalenderEvent, - StudentEvent, -} from "@/helpers/student/types"; -import { GetEventsByJobId, GetJobById } from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; -function transformEvents(events: CustomEvent[]): EventData[] { - const currentDate = new Date(); - - const sortedEvents = events.sort( - (a, b) => - new Date(a.startDateTime).getTime() - new Date(b.startDateTime).getTime(), - ); - - const result: EventData[] = sortedEvents.map((event) => { - const eventDate = new Date(event.startDateTime); - let status: string; - - if (eventDate < currentDate) { - status = "older-event"; - } else { - status = "newer-event"; - } - - return { - date: eventDate.toLocaleDateString("en-GB"), - status, - title: event.type, - description: event.metadata - }; - }); - - const firstFutureEventIndex = result.findIndex( - (event) => - new Date(event.date.split("/").reverse().join("-")) >= currentDate, - ); - if (firstFutureEventIndex !== -1) { - result[firstFutureEventIndex].status = "selected"; - } else if (result.length > 0) { - result[result.length - 1].status = "selected"; - } - - return result; -} - -const transformEventsCalender = (jobData: Job): CalenderEvent[] => { - return jobData.events.map((event) => ({ - day: new Date(event.startDateTime).setHours(0, 0, 0, 0), - description: event.metadata, - id: event.id, - label: "red", - timeFrom: event.startDateTime, - timeTo: event.endDateTime, - title: jobData.companyDetailsFilled.name, - })); -}; - -const storeCalenderEvents = (jobData: Job) => { - const transformedEvents = transformEventsCalender(jobData); - localStorage.setItem("savedEvents", JSON.stringify(transformedEvents)); -}; - -function formatNumber(num: number): string { - if (num >= 1000000000) { - return (num / 1000000000).toFixed(1).replace(/\.0$/, "") + "B"; - } - if (num >= 1000000) { - return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "M"; - } - if (num >= 1000) { - return (num / 1000).toFixed(1).replace(/\.0$/, "") + "K"; - } - return num.toString(); -} - -function getNextEvent(events: StudentEvent[]) { - - const now = new Date(); - - - let closestEvent = null; - let allEventsCompleted = true; - - for (const event of events) { - const eventEnd = new Date(event.endDateTime); - if (eventEnd > now) { - allEventsCompleted = false; - if (!closestEvent || eventEnd < new Date(closestEvent.endDateTime)) { - closestEvent = event; - } - } - } - - - if (allEventsCompleted) { - return "Process Completed"; - } else if (closestEvent) { - return `Upcoming Round ${closestEvent.roundNumber}: ${closestEvent.type}`; - } else { - return null; - } -} - -function convertDate(date: string){ - const dateString = new Date(date) - const formattedDateTime = dateString.toLocaleString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - hour: "numeric", - minute: "numeric", - second: "numeric", - hour12: true, - }); - - return formattedDateTime -} - -function getStatusClass(status) { - switch (status) { - case 'PENDING': - return 'text-yellow-500 font-semibold'; - case 'CLEARED': - return 'text-green-500 font-semibold'; - case 'REJECTED': - return 'text-red-500 font-semibold'; - case 'NOT APPLIED': - return 'text-cyan-500 font-semibold'; - default: - return ''; - } -} - -const JobPage = ({ params }: { params: { jobId: string } }) => { - const [jobData, setJobData] = useState(null); - const [studentEvents, setStudentEvents] = useState([]); - const [closestEvent, setClosestEvent] = useState(null); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchJobData = async () => { - try { - const data = await GetJobById(params.jobId); - setJobData(data); - storeCalenderEvents(data); - - const res = await GetEventsByJobId(params.jobId); - setStudentEvents(res); - setClosestEvent(getNextEvent(res)); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchJobData(); - }, [params.jobId]); - - return ( -
- {loading && ( -
- -
- )} - {jobData && ( - <> - {!closestEvent? ( -
- {jobData?.companyDetailsFilled.name} -
- ): ( -
-
- {jobData?.companyDetailsFilled.name} -
-
- {closestEvent} -
-
- )} -
- {jobData?.companyDetailsFilled.address.city},{" "} - {jobData?.companyDetailsFilled.address.state},{" "} - {jobData?.companyDetailsFilled.address.country} -
-
- -
-
-
-
Website
{" "} - - Link - -
-
-
Domain
{" "} -
- {jobData?.companyDetailsFilled.domains.length === 0 - ? "Not Available" - : jobData?.companyDetailsFilled.domains[0]} -
-
-
-
Category
{" "} -
{jobData?.companyDetailsFilled.category}
-
-
-
- Company Size -
{" "} -
{formatNumber(jobData?.companyDetailsFilled.size ?? 0)}
-
-
-
- Established -
{" "} -
{jobData?.companyDetailsFilled.yearOfEstablishment}
-
-
-
- -
-

Recruiter

- - - - Name - Designation - Email - Mobile Number - - - - - {jobData?.recruiterDetailsFilled.name} - - {jobData?.recruiterDetailsFilled.designation} - - {jobData?.recruiterDetailsFilled.email} - {jobData?.recruiterDetailsFilled.contact} - - - -
-
- -
-

Job Coordinators

- - - - Name - Role - Department - Email - Mobile Number - - - - {jobData?.jobCoordinators.map((coordinator, index) => ( - - {coordinator.tpcMember.student.user.name} - {coordinator.role} - {coordinator.tpcMember.student.program.department} - {coordinator.tpcMember.student.user.email} - {coordinator.tpcMember.student.user.contact} - - ))} - -
-
- -
-

Events

- - - - Round - Type - Start Date - End Date - Status - - - - {studentEvents.map((event, index) => ( - - {event.roundNumber} - {event.type} - {convertDate(event.startDateTime)} - {convertDate(event.endDateTime)} - - {event.studentStatus} - - - ))} - -
-
- -
- -
- -
-
-
-
- -
-
- -
-
-
- - )} -
- ); -}; - -export default JobPage; +"use client"; +import React, { useEffect, useState } from "react"; +import { Separator } from "@/components/ui/separator"; +import { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { Button } from "@/components/ui/button"; +import HorizontalTimeline from "@/components/HorizontalTimeline"; +import { + Job, + CustomEvent, + EventData, + CalenderEvent, + StudentEvent, +} from "@/helpers/student/types"; +import { GetEventsByJobId, GetJobById } from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; +function transformEvents(events: CustomEvent[]): EventData[] { + const currentDate = new Date(); + + const sortedEvents = events.sort( + (a, b) => + new Date(a.startDateTime).getTime() - new Date(b.startDateTime).getTime(), + ); + + const result: EventData[] = sortedEvents.map((event) => { + const eventDate = new Date(event.startDateTime); + let status: string; + + if (eventDate < currentDate) { + status = "older-event"; + } else { + status = "newer-event"; + } + + return { + date: eventDate.toLocaleDateString("en-GB"), + status, + title: event.type, + description: event.metadata + }; + }); + + const firstFutureEventIndex = result.findIndex( + (event) => + new Date(event.date.split("/").reverse().join("-")) >= currentDate, + ); + if (firstFutureEventIndex !== -1) { + result[firstFutureEventIndex].status = "selected"; + } else if (result.length > 0) { + result[result.length - 1].status = "selected"; + } + + return result; +} + +const transformEventsCalender = (jobData: Job): CalenderEvent[] => { + return jobData.events.map((event) => ({ + day: new Date(event.startDateTime).setHours(0, 0, 0, 0), + description: event.metadata, + id: event.id, + label: "red", + timeFrom: event.startDateTime, + timeTo: event.endDateTime, + title: jobData.companyDetailsFilled.name, + })); +}; + +const storeCalenderEvents = (jobData: Job) => { + const transformedEvents = transformEventsCalender(jobData); + localStorage.setItem("savedEvents", JSON.stringify(transformedEvents)); +}; + +function formatNumber(num: number): string { + if (num >= 1000000000) { + return (num / 1000000000).toFixed(1).replace(/\.0$/, "") + "B"; + } + if (num >= 1000000) { + return (num / 1000000).toFixed(1).replace(/\.0$/, "") + "M"; + } + if (num >= 1000) { + return (num / 1000).toFixed(1).replace(/\.0$/, "") + "K"; + } + return num.toString(); +} + +function getNextEvent(events: StudentEvent[]) { + + const now = new Date(); + + + let closestEvent = null; + let allEventsCompleted = true; + + for (const event of events) { + const eventEnd = new Date(event.endDateTime); + if (eventEnd > now) { + allEventsCompleted = false; + if (!closestEvent || eventEnd < new Date(closestEvent.endDateTime)) { + closestEvent = event; + } + } + } + + + if (allEventsCompleted) { + return "Process Completed"; + } else if (closestEvent) { + return `Upcoming Round ${closestEvent.roundNumber}: ${closestEvent.type}`; + } else { + return null; + } +} + +function convertDate(date: string){ + const dateString = new Date(date) + const formattedDateTime = dateString.toLocaleString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", + hour12: true, + }); + + return formattedDateTime +} + +function getStatusClass(status) { + switch (status) { + case 'PENDING': + return 'text-yellow-500 font-semibold'; + case 'CLEARED': + return 'text-green-500 font-semibold'; + case 'REJECTED': + return 'text-red-500 font-semibold'; + case 'NOT APPLIED': + return 'text-cyan-500 font-semibold'; + default: + return ''; + } +} + +const JobPage = ({ params }: { params: { jobId: string } }) => { + const [jobData, setJobData] = useState(null); + const [studentEvents, setStudentEvents] = useState([]); + const [closestEvent, setClosestEvent] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchJobData = async () => { + try { + const data = await GetJobById(params.jobId); + setJobData(data); + storeCalenderEvents(data); + + const res = await GetEventsByJobId(params.jobId); + setStudentEvents(res); + setClosestEvent(getNextEvent(res)); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchJobData(); + }, [params.jobId]); + + return ( +
+ {loading && ( +
+ +
+ )} + {jobData && ( + <> + {!closestEvent? ( +
+ {jobData?.companyDetailsFilled.name} +
+ ): ( +
+
+ {jobData?.companyDetailsFilled.name} +
+
+ {closestEvent} +
+
+ )} +
+ {jobData?.companyDetailsFilled.address.city},{" "} + {jobData?.companyDetailsFilled.address.state},{" "} + {jobData?.companyDetailsFilled.address.country} +
+
+ +
+
+
+
Website
{" "} + + Link + +
+
+
Domain
{" "} +
+ {jobData?.companyDetailsFilled.domains.length === 0 + ? "Not Available" + : jobData?.companyDetailsFilled.domains[0]} +
+
+
+
Category
{" "} +
{jobData?.companyDetailsFilled.category}
+
+
+
+ Company Size +
{" "} +
{formatNumber(jobData?.companyDetailsFilled.size ?? 0)}
+
+
+
+ Established +
{" "} +
{jobData?.companyDetailsFilled.yearOfEstablishment}
+
+
+
+ +
+

Recruiter

+ + + + Name + Designation + Email + Mobile Number + + + + + {jobData?.recruiterDetailsFilled.name} + + {jobData?.recruiterDetailsFilled.designation} + + {jobData?.recruiterDetailsFilled.email} + {jobData?.recruiterDetailsFilled.contact} + + + +
+
+ +
+

Job Coordinators

+ + + + Name + Role + Department + Email + Mobile Number + + + + {jobData?.jobCoordinators.map((coordinator, index) => ( + + {coordinator.tpcMember.student.user.name} + {coordinator.role} + {coordinator.tpcMember.student.program.department} + {coordinator.tpcMember.student.user.email} + {coordinator.tpcMember.student.user.contact} + + ))} + +
+
+ +
+

Events

+ + + + Round + Type + Start Date + End Date + Status + + + + {studentEvents.map((event, index) => ( + + {event.roundNumber} + {event.type} + {convertDate(event.startDateTime)} + {convertDate(event.endDateTime)} + + {event.studentStatus} + + + ))} + +
+
+ +
+ +
+ +
+
+
+
+ +
+
+ +
+
+
+ + )} +
+ ); +}; + +export default JobPage; diff --git a/src/app/(routes)/student/job/salary/[jobId]/page.tsx b/src/app/(routes)/student/job/salary/[jobId]/page.tsx index 4f50f065..21675eb0 100644 --- a/src/app/(routes)/student/job/salary/[jobId]/page.tsx +++ b/src/app/(routes)/student/job/salary/[jobId]/page.tsx @@ -1,68 +1,68 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import SalaryCard from "@/components/jobs/SalaryCard"; -import { GetJobById, GetResumes } from "@/helpers/student/api"; -import { Resume } from "@/helpers/student/types"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; - -interface Salary { - id: string; - salaryPeriod: string; - programs: string[]; - genders: string[]; - categories: string[]; - minCPI: number; - tenthMarks: number; - twelthMarks: number; - facultyApprovals: string[]; - baseSalary: number; - totalCTC: number; - takeHomeSalary: number; - grossSalary: number; - otherCompensations: number; -} - -const SalaryPage = ({ params }: { params: { jobId: string } }) => { - const [salaryData, setSalaryData] = useState([]); - const [resumes, setResumes] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchSalaryData = async () => { - try { - const data = await GetJobById(params.jobId); - setSalaryData(data.salaries); - - const res = await GetResumes(); - setResumes(res); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchSalaryData(); - }, [params.jobId]); - - return ( -
-
Salaries
- {loading && ( -
- -
- )} - {salaryData && - salaryData.map((item, index) => ( -
- -
- ))} -
- ); -}; - -export default SalaryPage; +"use client"; +import React, { useEffect, useState } from "react"; +import SalaryCard from "@/components/jobs/SalaryCard"; +import { GetJobById, GetResumes } from "@/helpers/student/api"; +import { Resume } from "@/helpers/student/types"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; + +interface Salary { + id: string; + salaryPeriod: string; + programs: string[]; + genders: string[]; + categories: string[]; + minCPI: number; + tenthMarks: number; + twelthMarks: number; + facultyApprovals: string[]; + baseSalary: number; + totalCTC: number; + takeHomeSalary: number; + grossSalary: number; + otherCompensations: number; +} + +const SalaryPage = ({ params }: { params: { jobId: string } }) => { + const [salaryData, setSalaryData] = useState([]); + const [resumes, setResumes] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchSalaryData = async () => { + try { + const data = await GetJobById(params.jobId); + setSalaryData(data.salaries); + + const res = await GetResumes(); + setResumes(res); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchSalaryData(); + }, [params.jobId]); + + return ( +
+
Salaries
+ {loading && ( +
+ +
+ )} + {salaryData && + salaryData.map((item, index) => ( +
+ +
+ ))} +
+ ); +}; + +export default SalaryPage; diff --git a/src/app/(routes)/student/jobs/page.tsx b/src/app/(routes)/student/jobs/page.tsx index 66fa5a51..46cc3123 100644 --- a/src/app/(routes)/student/jobs/page.tsx +++ b/src/app/(routes)/student/jobs/page.tsx @@ -1,49 +1,49 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import JobCard from "@/components/jobs/JobCard"; -import { GetJobs } from "@/helpers/student/api"; -import { Jobs } from "@/helpers/student/types"; -import toast from "react-hot-toast"; -import Loader from "@/components/Loader/loader"; -const StudentPage = () => { - const [jobs, setJobs] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchJobs = async () => { - try { - const data = await GetJobs(); - setJobs(data); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchJobs(); - }, []); - - return ( -
-
-

Jobs

-
-
- {loading && ( -
- -
- )} - {jobs && - jobs.map((job) => ( -
- -
- ))} -
-
- ); -}; - -export default StudentPage; +"use client"; +import React, { useEffect, useState } from "react"; +import JobCard from "@/components/jobs/JobCard"; +import { GetJobs } from "@/helpers/student/api"; +import { Jobs } from "@/helpers/student/types"; +import toast from "react-hot-toast"; +import Loader from "@/components/Loader/loader"; +const StudentPage = () => { + const [jobs, setJobs] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchJobs = async () => { + try { + const data = await GetJobs(); + setJobs(data); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchJobs(); + }, []); + + return ( +
+
+

Jobs

+
+
+ {loading && ( +
+ +
+ )} + {jobs && + jobs.map((job) => ( +
+ +
+ ))} +
+
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/student/layout.tsx b/src/app/(routes)/student/layout.tsx index bccda410..4ce199cb 100644 --- a/src/app/(routes)/student/layout.tsx +++ b/src/app/(routes)/student/layout.tsx @@ -1,11 +1,11 @@ -import Link from "next/link"; - -interface Props { - children: React.ReactNode; -} - -const StudentLayout = ({ children }: Props) => { - return
{children}
; -}; - -export default StudentLayout; +import Link from "next/link"; + +interface Props { + children: React.ReactNode; +} + +const StudentLayout = ({ children }: Props) => { + return
{children}
; +}; + +export default StudentLayout; diff --git a/src/app/(routes)/student/offCampus/page.tsx b/src/app/(routes)/student/offCampus/page.tsx index 265cc2cd..b9468a72 100644 --- a/src/app/(routes)/student/offCampus/page.tsx +++ b/src/app/(routes)/student/offCampus/page.tsx @@ -1,50 +1,50 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import OffCampusCard from "@/components/jobs/OffCampusCard"; -import { OffCampusOffer } from "@/helpers/student/types"; -import { GetOffCampusOffers } from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; - -const OffCampusPage = () => { - const [offCampusOffers, setOffCampusOffers] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchJobs = async () => { - try { - const oco = await GetOffCampusOffers(); - setOffCampusOffers(oco); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchJobs(); - // setJobs(Jobs); - }, []); - - return ( -
-
-

Off Campus Offers

-
- {loading && ( -
- -
- )} - {offCampusOffers && - offCampusOffers.map((job) => ( -
- -
- ))} -
- ); -}; - -export default OffCampusPage; +"use client"; +import React, { useEffect, useState } from "react"; +import OffCampusCard from "@/components/jobs/OffCampusCard"; +import { OffCampusOffer } from "@/helpers/student/types"; +import { GetOffCampusOffers } from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; + +const OffCampusPage = () => { + const [offCampusOffers, setOffCampusOffers] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchJobs = async () => { + try { + const oco = await GetOffCampusOffers(); + setOffCampusOffers(oco); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchJobs(); + // setJobs(Jobs); + }, []); + + return ( +
+
+

Off Campus Offers

+
+ {loading && ( +
+ +
+ )} + {offCampusOffers && + offCampusOffers.map((job) => ( +
+ +
+ ))} +
+ ); +}; + +export default OffCampusPage; diff --git a/src/app/(routes)/student/onCampus/page.tsx b/src/app/(routes)/student/onCampus/page.tsx index bd2b32a7..caa3702c 100644 --- a/src/app/(routes)/student/onCampus/page.tsx +++ b/src/app/(routes)/student/onCampus/page.tsx @@ -1,48 +1,48 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { GetOnCampusOffers } from "@/helpers/student/api"; -import { OnCampusOffers } from "@/helpers/student/types"; -import OnCampusCard from "@/components/jobs/OnCampusCard"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; -const StudentPage = () => { - const [onCampusOffers, setOnCampusOffers] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchOffers = async () => { - try { - const oco = await GetOnCampusOffers(); - setOnCampusOffers(oco); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchOffers(); - }, []); - - return ( -
-
-

On Campus Offers

-
- {loading && ( -
- -
- )} - {onCampusOffers && - onCampusOffers.map((job) => ( -
- -
- ))} -
- ); -}; - -export default StudentPage; +"use client"; +import React, { useEffect, useState } from "react"; +import { GetOnCampusOffers } from "@/helpers/student/api"; +import { OnCampusOffers } from "@/helpers/student/types"; +import OnCampusCard from "@/components/jobs/OnCampusCard"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; +const StudentPage = () => { + const [onCampusOffers, setOnCampusOffers] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchOffers = async () => { + try { + const oco = await GetOnCampusOffers(); + setOnCampusOffers(oco); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchOffers(); + }, []); + + return ( +
+
+

On Campus Offers

+
+ {loading && ( +
+ +
+ )} + {onCampusOffers && + onCampusOffers.map((job) => ( +
+ +
+ ))} +
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/student/opportunities/page.tsx b/src/app/(routes)/student/opportunities/page.tsx index 56628248..769a1ac0 100644 --- a/src/app/(routes)/student/opportunities/page.tsx +++ b/src/app/(routes)/student/opportunities/page.tsx @@ -1,49 +1,49 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import JobCard from "@/components/jobs/JobCard"; -import { GetOpportuinites } from "@/helpers/student/api"; -import { Jobs } from "@/helpers/student/types"; -import toast from "react-hot-toast"; -import Loader from "@/components/Loader/loader"; -const StudentPage = () => { - const [jobs, setJobs] = useState([]); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchJobs = async () => { - try { - const data = await GetOpportuinites(); - setJobs(data); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - fetchJobs(); - }, []); - - return ( -
-
-

Apply

-
-
- {loading && ( -
- -
- )} - {jobs && - jobs.map((job) => ( -
- -
- ))} -
-
- ); -}; - -export default StudentPage; +"use client"; +import React, { useEffect, useState } from "react"; +import JobCard from "@/components/jobs/JobCard"; +import { GetOpportuinites } from "@/helpers/student/api"; +import { Jobs } from "@/helpers/student/types"; +import toast from "react-hot-toast"; +import Loader from "@/components/Loader/loader"; +const StudentPage = () => { + const [jobs, setJobs] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchJobs = async () => { + try { + const data = await GetOpportuinites(); + setJobs(data); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + fetchJobs(); + }, []); + + return ( +
+
+

Apply

+
+
+ {loading && ( +
+ +
+ )} + {jobs && + jobs.map((job) => ( +
+ +
+ ))} +
+
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/student/page.tsx b/src/app/(routes)/student/page.tsx index c255de26..7203dbdf 100644 --- a/src/app/(routes)/student/page.tsx +++ b/src/app/(routes)/student/page.tsx @@ -1,197 +1,197 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { Separator } from "@/components/ui/separator"; -import { Button } from "@/components/ui/button"; -import { StudentDataType } from "@/helpers/student/types"; -import { GetStudentData } from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import Loader from "@/components/Loader/loader"; - -const ProfilePage = () => { - const [studentData, setStudentData] = useState(null); - const [totalPenalty, setTotalPenalty] = useState(0); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const fetchStudentData = async () => { - try { - const data = await GetStudentData(); - setStudentData(data); - - if (data) { - const total = data.penalties.reduce( - (sum: number, penalty) => sum + penalty.penalty, - 0, - ); - setTotalPenalty(total); - } - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - if (studentData === null) { - fetchStudentData(); - } - }); - - return ( - <> - {loading && ( -
- -
- )} - {studentData && ( -
-
-
- {studentData.user.name} -
-
- {studentData.rollNo} -
-
-
- -
-

Program

-
-
-
Course
{" "} -
{studentData.program.course}
-
-
-
Branch
{" "} -
{studentData.program.branch}
-
-
-
- Department -
{" "} -
{studentData.program.department}
-
-
-
Year
{" "} -
{studentData.program.year}
-
-
- -
- -
- -

Academics

-
-
-
- Category -
{" "} -
{studentData.category}
-
-
-
Gender
{" "} -
{studentData.gender}
-
-
-
CPI
{" "} -
{studentData.cpi}
-
-
-
- Tenth Marks -
{" "} -
{studentData.tenthMarks}
-
-
-
- Twelth Marks -
{" "} -
{studentData.twelthMarks}
-
-
- - {totalPenalty > 0 && ( - <> -
- -
- -

Penalties

- - - - Sr. - Reason - Penalty - - - - {studentData.penalties.map((item, index) => ( - - {index + 1} - {item.reason} - {item.penalty} - - ))} - - - - - - {totalPenalty} - - -
- - )} -
- -
- -

Seasons

- - - - Sr. - Year - Type - Action - - - - {studentData.registrations.map((item, index) => ( - - {index + 1} - {item.season.year} - {item.season.type} - - - - - ))} - -
-
-
-
- )} - - ); -}; - -export default ProfilePage; +"use client"; +import React, { useEffect, useState } from "react"; +import { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { Separator } from "@/components/ui/separator"; +import { Button } from "@/components/ui/button"; +import { StudentDataType } from "@/helpers/student/types"; +import { GetStudentData } from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import Loader from "@/components/Loader/loader"; + +const ProfilePage = () => { + const [studentData, setStudentData] = useState(null); + const [totalPenalty, setTotalPenalty] = useState(0); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchStudentData = async () => { + try { + const data = await GetStudentData(); + setStudentData(data); + + if (data) { + const total = data.penalties.reduce( + (sum: number, penalty) => sum + penalty.penalty, + 0, + ); + setTotalPenalty(total); + } + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + if (studentData === null) { + fetchStudentData(); + } + }); + + return ( + <> + {loading && ( +
+ +
+ )} + {studentData && ( +
+
+
+ {studentData.user.name} +
+
+ {studentData.rollNo} +
+
+
+ +
+

Program

+
+
+
Course
{" "} +
{studentData.program.course}
+
+
+
Branch
{" "} +
{studentData.program.branch}
+
+
+
+ Department +
{" "} +
{studentData.program.department}
+
+
+
Year
{" "} +
{studentData.program.year}
+
+
+ +
+ +
+ +

Academics

+
+
+
+ Category +
{" "} +
{studentData.category}
+
+
+
Gender
{" "} +
{studentData.gender}
+
+
+
CPI
{" "} +
{studentData.cpi}
+
+
+
+ Tenth Marks +
{" "} +
{studentData.tenthMarks}
+
+
+
+ Twelth Marks +
{" "} +
{studentData.twelthMarks}
+
+
+ + {totalPenalty > 0 && ( + <> +
+ +
+ +

Penalties

+ + + + Sr. + Reason + Penalty + + + + {studentData.penalties.map((item, index) => ( + + {index + 1} + {item.reason} + {item.penalty} + + ))} + + + + + + {totalPenalty} + + +
+ + )} +
+ +
+ +

Seasons

+ + + + Sr. + Year + Type + Action + + + + {studentData.registrations.map((item, index) => ( + + {index + 1} + {item.season.year} + {item.season.type} + + + + + ))} + +
+
+
+
+ )} + + ); +}; + +export default ProfilePage; diff --git a/src/app/(routes)/student/profile/page.tsx b/src/app/(routes)/student/profile/page.tsx index 3537321e..21a67d9d 100644 --- a/src/app/(routes)/student/profile/page.tsx +++ b/src/app/(routes)/student/profile/page.tsx @@ -1,223 +1,223 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { Separator } from "@/components/ui/separator"; -import { Button } from "@/components/ui/button"; -import { StudentDataType } from "@/helpers/student/types"; -import { GetStudentData, RegisterSeason } from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import Loader from "@/components/Loader/loader"; - -const ProfilePage = () => { - const [studentData, setStudentData] = useState(null); - const [totalPenalty, setTotalPenalty] = useState(0); - const [loading, setLoading] = useState(true); - - const handleRegister = async (seasonId: string, registered: boolean) => { - const res = await RegisterSeason(seasonId,registered); - if(res) { - if(registered) toast.success("Deregistered successfully"); - else toast.success("Registered successfully"); - setStudentData(prevState => { - if (!prevState) return null; - - const updatedRegistrations = prevState.registrations.map(registration => - registration.season.id === seasonId - ? { ...registration, registered: !registered } - : registration - ); - - return { - ...prevState, - registrations: updatedRegistrations - }; - }); - } - else{ - toast.error("Some Error Occured"); - } - } - - useEffect(() => { - const fetchStudentData = async () => { - try { - const data = await GetStudentData(); - setStudentData(data); - - if (data) { - const total = data.penalties.reduce( - (sum: number, penalty) => sum + penalty.penalty, - 0, - ); - setTotalPenalty(total); - } - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - if (studentData === null) { - fetchStudentData(); - } - }); - - return ( - <> - {loading && ( -
- -
- )} - {studentData && ( -
-
-
- {studentData.user.name} -
-
- {studentData.rollNo} -
-
-
- -
-

Program

-
-
-
Course
{" "} -
{studentData.program.course}
-
-
-
Branch
{" "} -
{studentData.program.branch}
-
-
-
- Department -
{" "} -
{studentData.program.department}
-
-
-
Year
{" "} -
{studentData.program.year}
-
-
- -
- -
- -

Academics

-
-
-
- Category -
{" "} -
{studentData.category}
-
-
-
Gender
{" "} -
{studentData.gender}
-
-
-
CPI
{" "} -
{studentData.cpi}
-
-
-
- Tenth Marks -
{" "} -
{studentData.tenthMarks}
-
-
-
- Twelth Marks -
{" "} -
{studentData.twelthMarks}
-
-
- - {totalPenalty > 0 && ( - <> -
- -
- -

Penalties

- - - - Sr. - Reason - Penalty - - - - {studentData.penalties.map((item, index) => ( - - {index + 1} - {item.reason} - {item.penalty} - - ))} - - - - - - {totalPenalty} - - -
- - )} -
- -
- -

Seasons

- - - - Sr. - Year - Type - Status - Action - - - - {studentData.registrations.map((item, index) => ( - - {index + 1} - {item.season.year} - {item.season.type} - {item.registered ? "Registered" : "Not Registered"} - - - - - ))} - -
-
-
-
- )} - - ); -}; - -export default ProfilePage; +"use client"; +import React, { useEffect, useState } from "react"; +import { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { Separator } from "@/components/ui/separator"; +import { Button } from "@/components/ui/button"; +import { StudentDataType } from "@/helpers/student/types"; +import { GetStudentData, RegisterSeason } from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import Loader from "@/components/Loader/loader"; + +const ProfilePage = () => { + const [studentData, setStudentData] = useState(null); + const [totalPenalty, setTotalPenalty] = useState(0); + const [loading, setLoading] = useState(true); + + const handleRegister = async (seasonId: string, registered: boolean) => { + const res = await RegisterSeason(seasonId,registered); + if(res) { + if(registered) toast.success("Deregistered successfully"); + else toast.success("Registered successfully"); + setStudentData(prevState => { + if (!prevState) return null; + + const updatedRegistrations = prevState.registrations.map(registration => + registration.season.id === seasonId + ? { ...registration, registered: !registered } + : registration + ); + + return { + ...prevState, + registrations: updatedRegistrations + }; + }); + } + else{ + toast.error("Some Error Occured"); + } + } + + useEffect(() => { + const fetchStudentData = async () => { + try { + const data = await GetStudentData(); + setStudentData(data); + + if (data) { + const total = data.penalties.reduce( + (sum: number, penalty) => sum + penalty.penalty, + 0, + ); + setTotalPenalty(total); + } + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + if (studentData === null) { + fetchStudentData(); + } + }); + + return ( + <> + {loading && ( +
+ +
+ )} + {studentData && ( +
+
+
+ {studentData.user.name} +
+
+ {studentData.rollNo} +
+
+
+ +
+

Program

+
+
+
Course
{" "} +
{studentData.program.course}
+
+
+
Branch
{" "} +
{studentData.program.branch}
+
+
+
+ Department +
{" "} +
{studentData.program.department}
+
+
+
Year
{" "} +
{studentData.program.year}
+
+
+ +
+ +
+ +

Academics

+
+
+
+ Category +
{" "} +
{studentData.category}
+
+
+
Gender
{" "} +
{studentData.gender}
+
+
+
CPI
{" "} +
{studentData.cpi}
+
+
+
+ Tenth Marks +
{" "} +
{studentData.tenthMarks}
+
+
+
+ Twelth Marks +
{" "} +
{studentData.twelthMarks}
+
+
+ + {totalPenalty > 0 && ( + <> +
+ +
+ +

Penalties

+ + + + Sr. + Reason + Penalty + + + + {studentData.penalties.map((item, index) => ( + + {index + 1} + {item.reason} + {item.penalty} + + ))} + + + + + + {totalPenalty} + + +
+ + )} +
+ +
+ +

Seasons

+ + + + Sr. + Year + Type + Status + Action + + + + {studentData.registrations.map((item, index) => ( + + {index + 1} + {item.season.year} + {item.season.type} + {item.registered ? "Registered" : "Not Registered"} + + + + + ))} + +
+
+
+
+ )} + + ); +}; + +export default ProfilePage; diff --git a/src/app/(routes)/student/resumes/page.tsx b/src/app/(routes)/student/resumes/page.tsx index 930d5a7d..89e50694 100644 --- a/src/app/(routes)/student/resumes/page.tsx +++ b/src/app/(routes)/student/resumes/page.tsx @@ -1,208 +1,208 @@ -"use client"; -import React, { useEffect, useState, ChangeEvent, FormEvent } from "react"; -import { - Table, - TableHeader, - TableBody, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { Separator } from "@/components/ui/separator"; -import { Button } from "@/components/ui/button"; -import { Resume } from "@/helpers/student/types"; -import { GetResumes, OpenResume, deleteResume } from "@/helpers/student/api"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; -import { uploadResume } from "@/helpers/student/api"; -import toast from "react-hot-toast"; -import loadingImg from "@/components/Faculty/loadingSpinner.svg"; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "@/components/ui/dialog"; -import Loader from "@/components/Loader/loader"; -const ResumePage = () => { - const [resumeData, setResumeData] = useState([]); - const [dialogOpen, setDialogOpen] = useState(false); - const [loading, setLoading] = useState(true); - - const fetchResumes = async () => { - try { - const data = await GetResumes(); - setResumeData(data); - } catch (error) { - toast.error("Error fetching data:"); - } finally { - setLoading(false); - } - }; - - const [file, setFile] = useState(null); - const [resumeName, setName] = useState(null); - - const handleFileChange = (event: ChangeEvent) => { - if (event.target.files) { - setFile(event.target.files[0]); - } - }; - - const handleNameChange = (event: ChangeEvent) => { - setName(event.target.value); - }; - - const handleOpenResume = async (filename: string) => { - OpenResume(filename); - }; - - const handleSubmit = async (event: FormEvent) => { - event.preventDefault(); - - if (!file) { - toast.error("Please select a file to upload."); - return; - } - - if (!resumeName) { - toast.error("Please enter a name."); - return; - } - - const formData = new FormData(); - formData.append("resume", file, file.name); - - const data = await uploadResume(formData, resumeName); - - if (data) { - toast.success("Uploaded Successfully"); - fetchResumes(); - setFile(null); - setDialogOpen(false); - } else { - toast.error("Error uploading file"); - } - }; - - const handleDelete = async (filename: string) => { - const res = await deleteResume(filename); - - if (res) { - toast.success("Deleted Successfully"); - fetchResumes(); - } else { - toast.error("Error deleting file"); - } - }; - - useEffect(() => { - if (resumeData.length === 0) { - fetchResumes(); - } - }); - - return ( - <> -
-
Resumes
- {loading && ( -
- -
- )} - {resumeData.length > 0 && ( - <> -
- -
- - - - Sr. - Name - Status - Delete - - - - {resumeData.map((item, index) => ( - - {index + 1} - -
handleOpenResume(item.filepath)} - > - {item.name} -
-
- - {item.verified ? "Verified" : "Not Verified"} - - - - -
- ))} -
-
- - )} -
- -
- - - - - - - Upload Resume - - Select and upload your resume file. - - -
-
- - -
-
- - -
- - - -
-
-
-
- - ); -}; - -export default ResumePage; +"use client"; +import React, { useEffect, useState, ChangeEvent, FormEvent } from "react"; +import { + Table, + TableHeader, + TableBody, + TableHead, + TableRow, + TableCell, +} from "@/components/ui/table"; +import { Separator } from "@/components/ui/separator"; +import { Button } from "@/components/ui/button"; +import { Resume } from "@/helpers/student/types"; +import { GetResumes, OpenResume, deleteResume } from "@/helpers/student/api"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { uploadResume } from "@/helpers/student/api"; +import toast from "react-hot-toast"; +import loadingImg from "@/components/Faculty/loadingSpinner.svg"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import Loader from "@/components/Loader/loader"; +const ResumePage = () => { + const [resumeData, setResumeData] = useState([]); + const [dialogOpen, setDialogOpen] = useState(false); + const [loading, setLoading] = useState(true); + + const fetchResumes = async () => { + try { + const data = await GetResumes(); + setResumeData(data); + } catch (error) { + toast.error("Error fetching data:"); + } finally { + setLoading(false); + } + }; + + const [file, setFile] = useState(null); + const [resumeName, setName] = useState(null); + + const handleFileChange = (event: ChangeEvent) => { + if (event.target.files) { + setFile(event.target.files[0]); + } + }; + + const handleNameChange = (event: ChangeEvent) => { + setName(event.target.value); + }; + + const handleOpenResume = async (filename: string) => { + OpenResume(filename); + }; + + const handleSubmit = async (event: FormEvent) => { + event.preventDefault(); + + if (!file) { + toast.error("Please select a file to upload."); + return; + } + + if (!resumeName) { + toast.error("Please enter a name."); + return; + } + + const formData = new FormData(); + formData.append("resume", file, file.name); + + const data = await uploadResume(formData, resumeName); + + if (data) { + toast.success("Uploaded Successfully"); + fetchResumes(); + setFile(null); + setDialogOpen(false); + } else { + toast.error("Error uploading file"); + } + }; + + const handleDelete = async (filename: string) => { + const res = await deleteResume(filename); + + if (res) { + toast.success("Deleted Successfully"); + fetchResumes(); + } else { + toast.error("Error deleting file"); + } + }; + + useEffect(() => { + if (resumeData.length === 0) { + fetchResumes(); + } + }); + + return ( + <> +
+
Resumes
+ {loading && ( +
+ +
+ )} + {resumeData.length > 0 && ( + <> +
+ +
+ + + + Sr. + Name + Status + Delete + + + + {resumeData.map((item, index) => ( + + {index + 1} + +
handleOpenResume(item.filepath)} + > + {item.name} +
+
+ + {item.verified ? "Verified" : "Not Verified"} + + + + +
+ ))} +
+
+ + )} +
+ +
+ + + + + + + Upload Resume + + Select and upload your resume file. + + +
+
+ + +
+
+ + +
+ + + +
+
+
+
+ + ); +}; + +export default ResumePage; diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 60ec6573..b80c9a76 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,11 +1,11 @@ -import NextAuth, { NextAuthOptions } from "next-auth"; -import { config } from "@/helpers/auth"; - -const authOptions: NextAuthOptions = { - ...config, - secret: process.env.NEXT_PUBLIC_SECRET, -}; - -const handler = NextAuth(authOptions); - -export { handler as GET, handler as POST }; +import NextAuth, { NextAuthOptions } from "next-auth"; +import { config } from "@/helpers/auth"; + +const authOptions: NextAuthOptions = { + ...config, + secret: process.env.NEXT_PUBLIC_SECRET, +}; + +const handler = NextAuth(authOptions); + +export { handler as GET, handler as POST }; diff --git a/src/app/error.tsx b/src/app/error.tsx index 81b0add6..e22d13d9 100644 --- a/src/app/error.tsx +++ b/src/app/error.tsx @@ -1,10 +1,10 @@ -"use client"; -import React from "react"; - -const ErrorPage = () => { - return ( -
-

Error Page

-
- ); -}; +"use client"; +import React from "react"; + +const ErrorPage = () => { + return ( +
+

Error Page

+
+ ); +}; diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 8342cc99..9bbf1b3e 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -1,12 +1,12 @@ -"use client"; -import Calendar from "@/components/Calendar/Calendar"; -import ContextWrapper from "@/components/Calendar/context/ContextWrapper"; -import "material-icons/iconfont/material-icons.css"; - -export default function CalendarView() { - return ( - - - - ); -} +"use client"; +import Calendar from "@/components/Calendar/Calendar"; +import ContextWrapper from "@/components/Calendar/context/ContextWrapper"; +import "material-icons/iconfont/material-icons.css"; + +export default function CalendarView() { + return ( + + + + ); +} diff --git a/src/app/globals.css b/src/app/globals.css index c2f2955b..79a79764 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,22 +1,22 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -:root { - --foreground-rgb: 0, 0, 0; - --background-start-rgb: 214, 219, 220; - --background-end-rgb: 255, 255, 255; -} - -@media (prefers-color-scheme: dark) { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - } -} - -body { - color: rgb(var(--foreground-rgb)); - background: rgb(232, 232, 232); -} +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-start-rgb: 0, 0, 0; + --background-end-rgb: 0, 0, 0; + } +} + +body { + color: rgb(var(--foreground-rgb)); + background: rgb(232, 232, 232); +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 05f2ee82..48fdf0c3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,67 +1,67 @@ -import MenuButton from "@/components/MenuButton"; -import "./globals.css"; -import type { Metadata } from "next"; -import { Inter } from "next/font/google"; -import Link from "next/link"; -import { ToggleProvider } from "@/contextProviders/ToggleProvider"; -import Sidebar from "@/components/Sidebar"; -import MainContent from "@/components/MainContent"; -import NavButtonGroup from "@/components/NavButtonGroup"; -import NextAuthProvider from "@/contextProviders/sessionProvider"; -import { Toaster } from "react-hot-toast"; -import { Providers } from "@/store/provider"; -import { Suspense } from "react"; - -const inter = Inter({ subsets: ["latin"] }); - -export const metadata: Metadata = { - title: "TPC Portal", - description: "Generated by create next app", -}; - -interface Props { - children: React.ReactNode; - auth: React.ReactNode; -} - -const RootLayout = async ({ children, auth }: Props) => { - const className = inter.className; - - return ( - - - -
- {/* */} - {/* Page Content */} - - - -
- {/* sidebar and main content share this space */} - Loading...}> - - - - {children} - -
- {auth} -
-
-
- - - ); -}; - -export default RootLayout; +import MenuButton from "@/components/MenuButton"; +import "./globals.css"; +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import Link from "next/link"; +import { ToggleProvider } from "@/contextProviders/ToggleProvider"; +import Sidebar from "@/components/Sidebar"; +import MainContent from "@/components/MainContent"; +import NavButtonGroup from "@/components/NavButtonGroup"; +import NextAuthProvider from "@/contextProviders/sessionProvider"; +import { Toaster } from "react-hot-toast"; +import { Providers } from "@/store/provider"; +import { Suspense } from "react"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "TPC Portal", + description: "Generated by create next app", +}; + +interface Props { + children: React.ReactNode; + auth: React.ReactNode; +} + +const RootLayout = async ({ children, auth }: Props) => { + const className = inter.className; + + return ( + + + +
+ {/* */} + {/* Page Content */} + + + +
+ {/* sidebar and main content share this space */} + Loading...}> + + + + {children} + +
+ {auth} +
+
+
+ + + ); +}; + +export default RootLayout; diff --git a/src/app/page.tsx b/src/app/page.tsx index d309e767..24254a92 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,27 +1,27 @@ -"use client"; - -import React from "react"; - -// To access the session on the server side, we make the component to be async -// To get the session we use await getServerSession(config), - -// import { getServerSession } from "next-auth"; -// import { config } from "@/helpers/auth"; - -// To access the session on the client side, we use useSession() function; - -import { useSession } from "next-auth/react"; - -const Home = () => { - // const session = await getServerSession(config); - - const { data: session, status } = useSession(); - console.log("session", session?.user); - - return ( -
- Home page -
- ); -}; -export default Home; +"use client"; + +import React from "react"; + +// To access the session on the server side, we make the component to be async +// To get the session we use await getServerSession(config), + +// import { getServerSession } from "next-auth"; +// import { config } from "@/helpers/auth"; + +// To access the session on the client side, we use useSession() function; + +import { useSession } from "next-auth/react"; + +const Home = () => { + // const session = await getServerSession(config); + + const { data: session, status } = useSession(); + console.log("session", session?.user); + + return ( +
+ Home page +
+ ); +}; +export default Home; diff --git a/src/components/Admin/AddForms.tsx b/src/components/Admin/AddForms.tsx index 65390c48..f55e6b7f 100644 --- a/src/components/Admin/AddForms.tsx +++ b/src/components/Admin/AddForms.tsx @@ -1,119 +1,119 @@ -import React, { useEffect, useState } from "react"; -import { JobCoordinatorFC, TPCMember } from "./types"; -import PersonIcon from "@mui/icons-material/Person"; -import Select from "react-select"; -import { Button } from "../ui/button"; -import { fetchTpcMembers, postJobCoordinator } from "@/helpers/api"; -import { CircularProgress } from "@mui/material"; -import toast from "react-hot-toast"; - -const JobCoordinatorForm = ({ jobId }: { jobId: string }) => { - const [tpcMembers, setTpcMembers] = useState(); - const [role, setRole] = useState("PRIMARY"); - const [loading, setLoading] = useState(true); - const options = tpcMembers?.map((member) => ({ - label: `${member.student.user.name} ${member.student.user.email}`, - value: member.id, - })); - const jobRoleOptions = [ - { - label: "PRIMARY", - value: "PRIMARY", - }, - { - label: "SECONDARY", - value: "SECONDARY", - }, - ]; - const [coordinator, setCoordinator] = useState(); - - const submitData = async () => { - await postJobCoordinator([ - { - jobId: jobId, - tpcMemberId: coordinator.id, - role: role, - }, - ]); - toast.success("Added! Reload to see changes"); - }; - - useEffect(() => { - const fetchData = async () => { - const data = await fetchTpcMembers(); - setTpcMembers(data); - setLoading(false); - }; - fetchData(); - }, []); - - return ( -
- {loading ? ( - - ) : ( - <> -
- -
- - { - setRole(newValue.value); - }} - /> - -
- )} - - )} -
- ); -}; - -export default JobCoordinatorForm; +import React, { useEffect, useState } from "react"; +import { JobCoordinatorFC, TPCMember } from "./types"; +import PersonIcon from "@mui/icons-material/Person"; +import Select from "react-select"; +import { Button } from "../ui/button"; +import { fetchTpcMembers, postJobCoordinator } from "@/helpers/api"; +import { CircularProgress } from "@mui/material"; +import toast from "react-hot-toast"; + +const JobCoordinatorForm = ({ jobId }: { jobId: string }) => { + const [tpcMembers, setTpcMembers] = useState(); + const [role, setRole] = useState("PRIMARY"); + const [loading, setLoading] = useState(true); + const options = tpcMembers?.map((member) => ({ + label: `${member.student.user.name} ${member.student.user.email}`, + value: member.id, + })); + const jobRoleOptions = [ + { + label: "PRIMARY", + value: "PRIMARY", + }, + { + label: "SECONDARY", + value: "SECONDARY", + }, + ]; + const [coordinator, setCoordinator] = useState(); + + const submitData = async () => { + await postJobCoordinator([ + { + jobId: jobId, + tpcMemberId: coordinator.id, + role: role, + }, + ]); + toast.success("Added! Reload to see changes"); + }; + + useEffect(() => { + const fetchData = async () => { + const data = await fetchTpcMembers(); + setTpcMembers(data); + setLoading(false); + }; + fetchData(); + }, []); + + return ( +
+ {loading ? ( + + ) : ( + <> +
+ +
+ + { + setRole(newValue.value); + }} + /> + +
+ )} + + )} +
+ ); +}; + +export default JobCoordinatorForm; diff --git a/src/components/Admin/AllSeasons.tsx b/src/components/Admin/AllSeasons.tsx index 30369596..39d053a1 100644 --- a/src/components/Admin/AllSeasons.tsx +++ b/src/components/Admin/AllSeasons.tsx @@ -1,288 +1,288 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import {SeasonFC, ApplicationFC } from "@/helpers/season/types"; -import { CircularProgress, Modal, Typography } from "@mui/material"; -import { seasonDTO } from "@/dto/SeasonDto"; -import {fetchSeasonData,} from "@/helpers/api"; -import { Button } from "../ui/button"; -import toast from "react-hot-toast"; -import Select from "react-select"; -import Table from "../NewTableComponent/Table"; -import generateColumns from "../NewTableComponent/ColumnMapping"; -import { addSeason } from "@/helpers/api"; - -const hiddenColumns = [ - "id", - "registered", - "season.id", - "student.id", - "student.program.id", - "student.user.id", -]; -const typeOptions = [ - "INTERN", - "PLACEMENT" -]; - -const options = typeOptions.map((option) => ({ - value: option, - label: option, - -})); - -export const AddSeason = ({ - open, - setOpen -}: { - open: boolean; - setOpen: (open: boolean) => void; -}) => { - const [formValues, setFormValues] = useState({ - year: "", - type: "" - }); - - const handleClose = () => setOpen(false); - - const handleChange = (e: React.ChangeEvent) => { - const { name, value, type, checked } = e.currentTarget; - setFormValues({ - ...formValues, - [name]: type === "checkbox" ? checked : value, - }); - }; - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - await addSeason([formValues]); - toast.success("Successfully added"); - window.location.reload(); - } catch { - toast.error("Some Error Occured"); - } - }; - - return ( - -
-
-
- - -
-
- - -
- -
-
-
- ); -}; - -export const AllSeasons = ({ seasons }: { seasons: [SeasonFC] }) => { - const [seasonYear, setSeasonYear] = useState(null); - - const changeRegistered = (seasonYear: string) => { - setSeasonYear(seasonYear); - }; - const changeUnRegistered = (seasonYear: string) => { - setSeasonYear(seasonYear); - }; - - return ( -
-
- - - - - - - - - {seasons.map((season, index) => ( - { - changeRegistered(season.year); - changeUnRegistered(season.year); - }} - > - - - - - - ))} - -
- Type - - Year -
- {season.type} - {season.year}
-
-

Registered

- {seasonYear ? ( -
- -
- ) : ( -
Select Season to view more
- )} -

Not Registered

- {seasonYear ? ( -
- -
- ) : ( -
Select Season to view more
- )} -
- ); -}; - - - - - -export const Registered = ({ - seasonYear -}: { - seasonYear: string; - seasons: SeasonFC[]; -}) => { - const [Registered, setRegistered] = useState<[ApplicationFC]>(null); - const [loading, setLoading] = useState(true); - const columns = generateColumns(seasonDTO); - const [loadingbutton, setloadingbutton] = useState(false); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - useEffect(() => { - setLoading(true); - setRegistered(null); - const fetchData = async () => { - try { - const jsonData = await fetchSeasonData(seasonYear,true); - setRegistered(jsonData); - - } catch (error) { - toast.error("Some error occured"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [seasonYear]); - - return ( -
- - {loading && ( -
- -
- )} - {Registered && ( - - )} - - ); -}; - - - - -export const UnRegistered = ({ - seasonYear -}: { - seasonYear: string; - seasons: SeasonFC[]; -}) => { - const [UnRegistered, setUnRegistered] = useState<[ApplicationFC]>(null); - const [loading, setLoading] = useState(true); - const columns = generateColumns(seasonDTO); - const [loadingbutton, setloadingbutton] = useState(false); - const visibleColumns = columns.filter( - (column: any) => !hiddenColumns.includes(column?.accessorKey), - ); - - useEffect(() => { - setLoading(true); - setUnRegistered(null); - const fetchData = async () => { - try { - const jsonData = await fetchSeasonData(seasonYear,null); - setUnRegistered(jsonData); - } catch (error) { - toast.error("Some error occured"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [seasonYear]); - - return ( -
- - {loading && ( -
- -
- )} - {UnRegistered && ( -
- )} - - ); -}; - - +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import {SeasonFC, ApplicationFC } from "@/helpers/season/types"; +import { CircularProgress, Modal, Typography } from "@mui/material"; +import { seasonDTO } from "@/dto/SeasonDto"; +import {fetchSeasonData,} from "@/helpers/api"; +import { Button } from "../ui/button"; +import toast from "react-hot-toast"; +import Select from "react-select"; +import Table from "../NewTableComponent/Table"; +import generateColumns from "../NewTableComponent/ColumnMapping"; +import { addSeason } from "@/helpers/api"; + +const hiddenColumns = [ + "id", + "registered", + "season.id", + "student.id", + "student.program.id", + "student.user.id", +]; +const typeOptions = [ + "INTERN", + "PLACEMENT" +]; + +const options = typeOptions.map((option) => ({ + value: option, + label: option, + +})); + +export const AddSeason = ({ + open, + setOpen +}: { + open: boolean; + setOpen: (open: boolean) => void; +}) => { + const [formValues, setFormValues] = useState({ + year: "", + type: "" + }); + + const handleClose = () => setOpen(false); + + const handleChange = (e: React.ChangeEvent) => { + const { name, value, type, checked } = e.currentTarget; + setFormValues({ + ...formValues, + [name]: type === "checkbox" ? checked : value, + }); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + await addSeason([formValues]); + toast.success("Successfully added"); + window.location.reload(); + } catch { + toast.error("Some Error Occured"); + } + }; + + return ( + +
+
+
+ + +
+
+ + +
+ + +
+
+ ); +}; + +export const AllSeasons = ({ seasons }: { seasons: [SeasonFC] }) => { + const [seasonYear, setSeasonYear] = useState(null); + + const changeRegistered = (seasonYear: string) => { + setSeasonYear(seasonYear); + }; + const changeUnRegistered = (seasonYear: string) => { + setSeasonYear(seasonYear); + }; + + return ( +
+
+
+ + + + + + + + {seasons.map((season, index) => ( + { + changeRegistered(season.year); + changeUnRegistered(season.year); + }} + > + + + + + + ))} + +
+ Type + + Year +
+ {season.type} + {season.year}
+
+

Registered

+ {seasonYear ? ( +
+ +
+ ) : ( +
Select Season to view more
+ )} +

Not Registered

+ {seasonYear ? ( +
+ +
+ ) : ( +
Select Season to view more
+ )} + + ); +}; + + + + + +export const Registered = ({ + seasonYear +}: { + seasonYear: string; + seasons: SeasonFC[]; +}) => { + const [Registered, setRegistered] = useState<[ApplicationFC]>(null); + const [loading, setLoading] = useState(true); + const columns = generateColumns(seasonDTO); + const [loadingbutton, setloadingbutton] = useState(false); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + useEffect(() => { + setLoading(true); + setRegistered(null); + const fetchData = async () => { + try { + const jsonData = await fetchSeasonData(seasonYear,true); + setRegistered(jsonData); + + } catch (error) { + toast.error("Some error occured"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [seasonYear]); + + return ( +
+ + {loading && ( +
+ +
+ )} + {Registered && ( + + )} + + ); +}; + + + + +export const UnRegistered = ({ + seasonYear +}: { + seasonYear: string; + seasons: SeasonFC[]; +}) => { + const [UnRegistered, setUnRegistered] = useState<[ApplicationFC]>(null); + const [loading, setLoading] = useState(true); + const columns = generateColumns(seasonDTO); + const [loadingbutton, setloadingbutton] = useState(false); + const visibleColumns = columns.filter( + (column: any) => !hiddenColumns.includes(column?.accessorKey), + ); + + useEffect(() => { + setLoading(true); + setUnRegistered(null); + const fetchData = async () => { + try { + const jsonData = await fetchSeasonData(seasonYear,null); + setUnRegistered(jsonData); + } catch (error) { + toast.error("Some error occured"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [seasonYear]); + + return ( +
+ + {loading && ( +
+ +
+ )} + {UnRegistered && ( +
+ )} + + ); +}; + + diff --git a/src/components/Admin/JobEvents.tsx b/src/components/Admin/JobEvents.tsx index f8cea203..0a3a01f2 100644 --- a/src/components/Admin/JobEvents.tsx +++ b/src/components/Admin/JobEvents.tsx @@ -1,589 +1,589 @@ -"use client"; -import React from "react"; -import { useState, useEffect } from "react"; -import { EventFC, ApplicationFC, SalaryFC } from "@/helpers/recruiter/types"; -import { CircularProgress, Modal, Typography } from "@mui/material"; -import VerifiedIcon from "@mui/icons-material/Verified"; -import { - addEvent, - fetchEventById, - getResumeFile, - getStudentSalaryOffers, - postOnCampusOffer, - promoteStudent, -} from "@/helpers/api"; -import { Button } from "../ui/button"; -import toast from "react-hot-toast"; -import Select from "react-select"; -import { Unstable_NumberInput as NumberInput } from "@mui/base/Unstable_NumberInput"; -import Table from "../NewTableComponent/Table"; -import generateColumns from "../NewTableComponent/ColumnMapping"; - -const typeOptions = [ - "POLL", - "PPT", - "INTERVIEW", - "TEST", - "APPLICATION", - "COMPLETED", -]; - -const options = typeOptions.map((option) => ({ - value: option, - label: option, -})); - -export const AddEvent = ({ - open, - setOpen, - jobId, -}: { - open: boolean; - setOpen: (open: boolean) => void; - jobId: string; -}) => { - const [formValues, setFormValues] = useState({ - jobId: jobId, - roundNumber: 0, - type: "", - metadata: "", - startDateTime: "", - endDateTime: "", - visibleToRecruiter: false, - }); - - const handleClose = () => setOpen(false); - - const handleChange = (e: React.ChangeEvent) => { - const { name, value, type, checked } = e.currentTarget; - setFormValues({ - ...formValues, - [name]: type === "checkbox" ? checked : value, - }); - }; - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - await addEvent([formValues]); - toast.success("Successfully added"); - window.location.reload(); - } catch { - toast.error("Some Error Occured"); - } - }; - - return ( - -
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
- - -
-
- ); -}; - -const PromoteStudent = ({ - open, - students, - onClose, - events, -}: { - open: boolean; - students: any[]; - onClose: () => void; - events: EventFC[]; -}) => { - const [roundNumber, setRoundNumber] = useState(0); - const studentIds = students.map((student) => student.id); - const [eventId, setEventId] = useState(); - useEffect(() => { - const setCurrentEvent = events.forEach((event) => { - if (event.roundNumber == roundNumber) { - setEventId(event.id); - return event; - } - }); - setCurrentEvent; - }, [roundNumber]); - - const updateEvent = async () => { - await promoteStudent({ studentIds }, eventId); - toast.success("Successfully promoted!"); - onClose(); - }; - - return ( - -
-
- Promote / Demote students :{" "} - {students.map((student) => `${student.name}, `)} to
- - { - setRoundNumber(newValue); - }} - max={events.length} - min={0} - slotProps={{ - input: { - className: - "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", - }, - }} - placeholder="0" - required - /> - -
-
-
- ); -}; - -const MakeJobOfferModal = ({ - open, - students, - onClose, - events, - lastEvent, -}: { - open: boolean; - students: any[]; - onClose: () => void; - events: EventFC[]; - lastEvent: EventFC; -}) => { - const studentIds = students.map((student) => student.id); - const [salaries, setSalaries] = useState(); - const columns = generateColumns([ - { - select: "", - baseSalary: 0, - totalCTC: 0, - takeHomeSalary: 0, - grossSalary: 0, - otherCompensations: 0, - salaryPeriod: "string", - job: { - role: "string", - company: { - name: "string", - }, - }, - }, - ]); - - const makeOffer = async (salaryId: string) => { - await postOnCampusOffer([ - { - salaryId: salaryId, - studentId: studentIds[0], - status: "ACCEPTED", - }, - ]); - toast.success("Made a successful offer!"); - window.location.reload(); - }; - - useEffect(() => { - const fetchSalaries = async () => { - const salaries = await getStudentSalaryOffers( - lastEvent.job.id, - studentIds[0], - ); - const newSalaries = salaries.map((salary) => ({ - select: ( - - ), - ...salary, - })); - setSalaries(newSalaries); - }; - fetchSalaries(); - }, []); - - return ( - -
-
- - Select Salary - - {salaries ? ( -
-
- - ) : ( -
- -
- )} - - - - ); -}; - -export const JobEvents = ({ events }: { events: [EventFC] }) => { - const [eventId, setEventId] = useState(null); - - const changeApplications = (eventId: string) => { - setEventId(eventId); - }; - - return ( -
-
-
- - - - - - - - - - - {events.map((event, index) => ( - { - changeApplications(event.id); - }} - > - - - - - - - ))} - -
- Round Number - - Type - - Meta Data - - Start Date - - End Date -
- {event.roundNumber} - {event.type}{event.metadata} - {new Date(event.startDateTime).toLocaleString()} - - {new Date(event.endDateTime).toLocaleString()} -
-
-

Applications

- {eventId ? ( -
- -
- ) : ( -
Select Event to view more
- )} - - ); -}; - -export const Applications = ({ - eventId, - events, -}: { - eventId: string; - events: EventFC[]; -}) => { - const [applications, setApplications] = useState<[ApplicationFC]>(null); - var lastEvent: EventFC; - events.forEach((event) => { - if (lastEvent) { - if (lastEvent.roundNumber < event.roundNumber) { - lastEvent = event; - } - } else { - lastEvent = event; - } - }); - const [loading, setLoading] = useState(true); - const [promoteStudents, setPromoteStudents] = useState([]); - const [seed, setSeed] = useState(0); - - useEffect(() => { - setLoading(true); - setApplications(null); - const fetchData = async () => { - try { - const jsonData: EventFC = await fetchEventById(eventId); - setApplications(jsonData.applications); - } catch (error) { - toast.error("Some error occured"); - } finally { - setLoading(false); - } - }; - - fetchData(); - }, [eventId, seed]); - - return ( -
- {lastEvent.id == eventId && promoteStudents.length > 0 ? ( - 0} - students={promoteStudents} - onClose={() => { - setPromoteStudents([]); - setSeed(seed + 1); - }} - events={events} - lastEvent={lastEvent} - /> - ) : ( - 0} - students={promoteStudents} - onClose={() => { - setPromoteStudents([]); - setSeed(seed + 1); - }} - events={events} - /> - )} - {loading && ( -
- -
- )} - {applications && ( - - - - - - - - - - - - {applications.map((application, index) => ( - - - - - - - - ))} - -
- Roll Number - - Name - - Email - - Resume - - Promote -
- {application.student.rollNo} - {application.student.user.name}{application.student.user.email} getResumeFile(application.resume.filepath)} - > - {application.resume.filepath}{" "} - {application.resume.verified && } - - {lastEvent.id == eventId ? ( - - ) : ( - - )} -
- )} -
- ); -}; +"use client"; +import React from "react"; +import { useState, useEffect } from "react"; +import { EventFC, ApplicationFC, SalaryFC } from "@/helpers/recruiter/types"; +import { CircularProgress, Modal, Typography } from "@mui/material"; +import VerifiedIcon from "@mui/icons-material/Verified"; +import { + addEvent, + fetchEventById, + getResumeFile, + getStudentSalaryOffers, + postOnCampusOffer, + promoteStudent, +} from "@/helpers/api"; +import { Button } from "../ui/button"; +import toast from "react-hot-toast"; +import Select from "react-select"; +import { Unstable_NumberInput as NumberInput } from "@mui/base/Unstable_NumberInput"; +import Table from "../NewTableComponent/Table"; +import generateColumns from "../NewTableComponent/ColumnMapping"; + +const typeOptions = [ + "POLL", + "PPT", + "INTERVIEW", + "TEST", + "APPLICATION", + "COMPLETED", +]; + +const options = typeOptions.map((option) => ({ + value: option, + label: option, +})); + +export const AddEvent = ({ + open, + setOpen, + jobId, +}: { + open: boolean; + setOpen: (open: boolean) => void; + jobId: string; +}) => { + const [formValues, setFormValues] = useState({ + jobId: jobId, + roundNumber: 0, + type: "", + metadata: "", + startDateTime: "", + endDateTime: "", + visibleToRecruiter: false, + }); + + const handleClose = () => setOpen(false); + + const handleChange = (e: React.ChangeEvent) => { + const { name, value, type, checked } = e.currentTarget; + setFormValues({ + ...formValues, + [name]: type === "checkbox" ? checked : value, + }); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + await addEvent([formValues]); + toast.success("Successfully added"); + window.location.reload(); + } catch { + toast.error("Some Error Occured"); + } + }; + + return ( + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+ ); +}; + +const PromoteStudent = ({ + open, + students, + onClose, + events, +}: { + open: boolean; + students: any[]; + onClose: () => void; + events: EventFC[]; +}) => { + const [roundNumber, setRoundNumber] = useState(0); + const studentIds = students.map((student) => student.id); + const [eventId, setEventId] = useState(); + useEffect(() => { + const setCurrentEvent = events.forEach((event) => { + if (event.roundNumber == roundNumber) { + setEventId(event.id); + return event; + } + }); + setCurrentEvent; + }, [roundNumber]); + + const updateEvent = async () => { + await promoteStudent({ studentIds }, eventId); + toast.success("Successfully promoted!"); + onClose(); + }; + + return ( + +
+
+ Promote / Demote students :{" "} + {students.map((student) => `${student.name}, `)} to
+ + { + setRoundNumber(newValue); + }} + max={events.length} + min={0} + slotProps={{ + input: { + className: + "bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", + }, + }} + placeholder="0" + required + /> + +
+
+
+ ); +}; + +const MakeJobOfferModal = ({ + open, + students, + onClose, + events, + lastEvent, +}: { + open: boolean; + students: any[]; + onClose: () => void; + events: EventFC[]; + lastEvent: EventFC; +}) => { + const studentIds = students.map((student) => student.id); + const [salaries, setSalaries] = useState(); + const columns = generateColumns([ + { + select: "", + baseSalary: 0, + totalCTC: 0, + takeHomeSalary: 0, + grossSalary: 0, + otherCompensations: 0, + salaryPeriod: "string", + job: { + role: "string", + company: { + name: "string", + }, + }, + }, + ]); + + const makeOffer = async (salaryId: string) => { + await postOnCampusOffer([ + { + salaryId: salaryId, + studentId: studentIds[0], + status: "ACCEPTED", + }, + ]); + toast.success("Made a successful offer!"); + window.location.reload(); + }; + + useEffect(() => { + const fetchSalaries = async () => { + const salaries = await getStudentSalaryOffers( + lastEvent.job.id, + studentIds[0], + ); + const newSalaries = salaries.map((salary) => ({ + select: ( + + ), + ...salary, + })); + setSalaries(newSalaries); + }; + fetchSalaries(); + }, []); + + return ( + +
+
+ + Select Salary + + {salaries ? ( +
+ + + ) : ( +
+ +
+ )} + + + + ); +}; + +export const JobEvents = ({ events }: { events: [EventFC] }) => { + const [eventId, setEventId] = useState(null); + + const changeApplications = (eventId: string) => { + setEventId(eventId); + }; + + return ( +
+
+
+ + + + + + + + + + + {events.map((event, index) => ( + { + changeApplications(event.id); + }} + > + + + + + + + ))} + +
+ Round Number + + Type + + Meta Data + + Start Date + + End Date +
+ {event.roundNumber} + {event.type}{event.metadata} + {new Date(event.startDateTime).toLocaleString()} + + {new Date(event.endDateTime).toLocaleString()} +
+
+

Applications

+ {eventId ? ( +
+ +
+ ) : ( +
Select Event to view more
+ )} +
+ ); +}; + +export const Applications = ({ + eventId, + events, +}: { + eventId: string; + events: EventFC[]; +}) => { + const [applications, setApplications] = useState<[ApplicationFC]>(null); + var lastEvent: EventFC; + events.forEach((event) => { + if (lastEvent) { + if (lastEvent.roundNumber < event.roundNumber) { + lastEvent = event; + } + } else { + lastEvent = event; + } + }); + const [loading, setLoading] = useState(true); + const [promoteStudents, setPromoteStudents] = useState([]); + const [seed, setSeed] = useState(0); + + useEffect(() => { + setLoading(true); + setApplications(null); + const fetchData = async () => { + try { + const jsonData: EventFC = await fetchEventById(eventId); + setApplications(jsonData.applications); + } catch (error) { + toast.error("Some error occured"); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [eventId, seed]); + + return ( +
+ {lastEvent.id == eventId && promoteStudents.length > 0 ? ( + 0} + students={promoteStudents} + onClose={() => { + setPromoteStudents([]); + setSeed(seed + 1); + }} + events={events} + lastEvent={lastEvent} + /> + ) : ( + 0} + students={promoteStudents} + onClose={() => { + setPromoteStudents([]); + setSeed(seed + 1); + }} + events={events} + /> + )} + {loading && ( +
+ +
+ )} + {applications && ( + + + + + + + + + + + + {applications.map((application, index) => ( + + + + + + + + ))} + +
+ Roll Number + + Name + + Email + + Resume + + Promote +
+ {application.student.rollNo} + {application.student.user.name}{application.student.user.email} getResumeFile(application.resume.filepath)} + > + {application.resume.filepath}{" "} + {application.resume.verified && } + + {lastEvent.id == eventId ? ( + + ) : ( + + )} +
+ )} +
+ ); +}; diff --git a/src/components/Admin/Profile.tsx b/src/components/Admin/Profile.tsx index 48548e64..77d1e01c 100644 --- a/src/components/Admin/Profile.tsx +++ b/src/components/Admin/Profile.tsx @@ -1,76 +1,76 @@ -"use client"; -import React, { useEffect, useState } from "react"; -import Cookies from "js-cookie"; -import { getUserById } from "@/helpers/api"; -import { ProfileLoader, ProfileNavLoader } from "../Loader/loaders"; -import PersonIcon from "@mui/icons-material/Person"; - -interface ProfileProps { - name: string; - email: string; - contact: string; - role: string; -} - -const AdminProfile = () => { - const [profile, setProfile] = useState(); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const setData = async () => { - const user = Cookies.get("user"); - const userId = JSON.parse(user).id; - const data = await getUserById(userId); - setProfile(data[0]); - setLoading(false); - }; - setData(); - }, []); - - return ( -
-
-
-
-
-
- -
- {loading ? ( - - ) : ( - <> -
{profile.name}
-

{profile.role}

- - )} -
-
-
-
- Self Details -
- {loading ? ( - - ) : ( -
-
- Email: - {profile.email} -
-
- Contact: - {profile.contact} -
-
- )} -
-
-
-
-
-
- ); -}; - -export default AdminProfile; +"use client"; +import React, { useEffect, useState } from "react"; +import Cookies from "js-cookie"; +import { getUserById } from "@/helpers/api"; +import { ProfileLoader, ProfileNavLoader } from "../Loader/loaders"; +import PersonIcon from "@mui/icons-material/Person"; + +interface ProfileProps { + name: string; + email: string; + contact: string; + role: string; +} + +const AdminProfile = () => { + const [profile, setProfile] = useState(); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const setData = async () => { + const user = Cookies.get("user"); + const userId = JSON.parse(user).id; + const data = await getUserById(userId); + setProfile(data[0]); + setLoading(false); + }; + setData(); + }, []); + + return ( +
+
+
+
+
+
+ +
+ {loading ? ( + + ) : ( + <> +
{profile.name}
+

{profile.role}

+ + )} +
+
+
+
+ Self Details +
+ {loading ? ( + + ) : ( +
+
+ Email: + {profile.email} +
+
+ Contact: + {profile.contact} +
+
+ )} +
+
+
+
+
+
+ ); +}; + +export default AdminProfile; diff --git a/src/components/Admin/types.tsx b/src/components/Admin/types.tsx index 659bf89b..3d01be8b 100644 --- a/src/components/Admin/types.tsx +++ b/src/components/Admin/types.tsx @@ -1,32 +1,32 @@ - -interface Program { - id: string; - branch: string; - course: string; - year: string; - department: string; -} - -interface User { - id: string; - name: string; - email: string; - contact: string; -} - -interface Student { - id: string; - program: Program; - user: User; -} - -export interface TPCMember { - id: string; - role: string; - student: Student; -} -export interface JobCoordinatorFC { - id: string; - role: string; - tpcMember: TPCMember; -} + +interface Program { + id: string; + branch: string; + course: string; + year: string; + department: string; +} + +interface User { + id: string; + name: string; + email: string; + contact: string; +} + +interface Student { + id: string; + program: Program; + user: User; +} + +export interface TPCMember { + id: string; + role: string; + student: Student; +} +export interface JobCoordinatorFC { + id: string; + role: string; + tpcMember: TPCMember; +} diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 6cc1d06d..e322d1b3 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -1,45 +1,45 @@ -import React, { useState, useContext, useEffect } from "react"; -import { getMonth } from "./CalenderComponent/util"; -import { getWeek } from "./CalenderComponent/util"; -import { getDate } from "./CalenderComponent/util"; -import Month from "./CalenderComponent/Month"; -import GlobalContext from "./context/GlobalContext"; -import CalendarHeader from "./CalenderComponent/CalendarHeader"; -import EventDetails from "./CalenderComponent/EventDetails"; -import SidebarCalendar from "./CalenderComponent/SidebarCalendar"; -import WeeklyView from "./CalenderComponent/WeeklyView"; -import DailyView from "./CalenderComponent/DailyView"; - -export default function Calendar() { - const { monthIndex, showEventModal, Current_view, weekOffset, dateOffset } = - useContext(GlobalContext); - const [currentMonth, setCurrentMonth] = useState(getMonth()); - const [currentWeek, setCurrentWeek] = useState(getWeek(weekOffset)); - const [displayDate, setDisplayDate] = useState(getDate(dateOffset)); - - useEffect(() => { - setCurrentMonth(getMonth(monthIndex)); - }, [monthIndex]); - useEffect(() => { - setCurrentWeek(getWeek(weekOffset)); - }, [weekOffset]); - useEffect(() => { - setDisplayDate(getDate(dateOffset)); - }, [dateOffset]); - - return ( -
- {showEventModal && } - -
- -
- - {Current_view == "Month" && } - {Current_view == "Week" && } - {Current_view == "Day" && } -
-
-
- ); -} +import React, { useState, useContext, useEffect } from "react"; +import { getMonth } from "./CalenderComponent/util"; +import { getWeek } from "./CalenderComponent/util"; +import { getDate } from "./CalenderComponent/util"; +import Month from "./CalenderComponent/Month"; +import GlobalContext from "./context/GlobalContext"; +import CalendarHeader from "./CalenderComponent/CalendarHeader"; +import EventDetails from "./CalenderComponent/EventDetails"; +import SidebarCalendar from "./CalenderComponent/SidebarCalendar"; +import WeeklyView from "./CalenderComponent/WeeklyView"; +import DailyView from "./CalenderComponent/DailyView"; + +export default function Calendar() { + const { monthIndex, showEventModal, Current_view, weekOffset, dateOffset } = + useContext(GlobalContext); + const [currentMonth, setCurrentMonth] = useState(getMonth()); + const [currentWeek, setCurrentWeek] = useState(getWeek(weekOffset)); + const [displayDate, setDisplayDate] = useState(getDate(dateOffset)); + + useEffect(() => { + setCurrentMonth(getMonth(monthIndex)); + }, [monthIndex]); + useEffect(() => { + setCurrentWeek(getWeek(weekOffset)); + }, [weekOffset]); + useEffect(() => { + setDisplayDate(getDate(dateOffset)); + }, [dateOffset]); + + return ( +
+ {showEventModal && } + +
+ +
+ + {Current_view == "Month" && } + {Current_view == "Week" && } + {Current_view == "Day" && } +
+
+
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/CalendarHeader.tsx b/src/components/Calendar/CalenderComponent/CalendarHeader.tsx index a1121b9c..0b730ee5 100644 --- a/src/components/Calendar/CalenderComponent/CalendarHeader.tsx +++ b/src/components/Calendar/CalenderComponent/CalendarHeader.tsx @@ -1,115 +1,115 @@ -import React, { useContext, useState } from "react"; -import dayjs from "dayjs"; -import GlobalContext from "../context/GlobalContext"; - -export default function CalendarHeader() { - const { - monthIndex, - setMonthIndex, - Current_view, - SetCurrent_view, - weekOffset, - setWeekOffset, - dateOffset, - setDateOffset, - } = useContext(GlobalContext); - const [Isopen, SetIsOpen] = useState(false); - const drop_down_list = ["Day", "Week", "Month"]; - - function change_view(view_name: string) { - SetCurrent_view(view_name); - } - function handlePrevMonth() { - { - Current_view == "Month" && setMonthIndex(monthIndex - 1); - } - { - Current_view == "Week" && setWeekOffset(weekOffset - 1); - } - { - Current_view == "Day" && setDateOffset(dateOffset - 1); - } - } - function handleNextMonth() { - { - Current_view == "Month" && setMonthIndex(monthIndex + 1); - } - { - Current_view == "Week" && setWeekOffset(weekOffset + 1); - } - { - Current_view == "Day" && setDateOffset(dateOffset + 1); - } - } - function handleReset() { - setMonthIndex( - monthIndex === dayjs().month() ? monthIndex : dayjs().month(), - ); - setWeekOffset(0); - setDateOffset(0); - } - - return ( -
- - - - -

- {Current_view == "Month" && - dayjs(new Date(dayjs().year(), monthIndex)).format("MMMM YYYY")} - {Current_view == "Week" && - (() => { - const startOfWeek = dayjs() - .add(weekOffset, "week") - .startOf("week"); - const endOfWeek = dayjs().add(weekOffset, "week").endOf("week"); - const startMonth = startOfWeek.format("MMMM"); - const endMonth = endOfWeek.format("MMMM"); - const year = startOfWeek.format("YYYY"); - return startMonth === endMonth - ? `${startMonth} ${year}` - : `${startMonth}-${endMonth} ${year}`; - })()} - - {Current_view == "Day" && - dayjs().add(dateOffset, "day").format("DD MMMM YYYY")} -

- -
- -
- ); -} +import React, { useContext, useState } from "react"; +import dayjs from "dayjs"; +import GlobalContext from "../context/GlobalContext"; + +export default function CalendarHeader() { + const { + monthIndex, + setMonthIndex, + Current_view, + SetCurrent_view, + weekOffset, + setWeekOffset, + dateOffset, + setDateOffset, + } = useContext(GlobalContext); + const [Isopen, SetIsOpen] = useState(false); + const drop_down_list = ["Day", "Week", "Month"]; + + function change_view(view_name: string) { + SetCurrent_view(view_name); + } + function handlePrevMonth() { + { + Current_view == "Month" && setMonthIndex(monthIndex - 1); + } + { + Current_view == "Week" && setWeekOffset(weekOffset - 1); + } + { + Current_view == "Day" && setDateOffset(dateOffset - 1); + } + } + function handleNextMonth() { + { + Current_view == "Month" && setMonthIndex(monthIndex + 1); + } + { + Current_view == "Week" && setWeekOffset(weekOffset + 1); + } + { + Current_view == "Day" && setDateOffset(dateOffset + 1); + } + } + function handleReset() { + setMonthIndex( + monthIndex === dayjs().month() ? monthIndex : dayjs().month(), + ); + setWeekOffset(0); + setDateOffset(0); + } + + return ( +
+ + + + +

+ {Current_view == "Month" && + dayjs(new Date(dayjs().year(), monthIndex)).format("MMMM YYYY")} + {Current_view == "Week" && + (() => { + const startOfWeek = dayjs() + .add(weekOffset, "week") + .startOf("week"); + const endOfWeek = dayjs().add(weekOffset, "week").endOf("week"); + const startMonth = startOfWeek.format("MMMM"); + const endMonth = endOfWeek.format("MMMM"); + const year = startOfWeek.format("YYYY"); + return startMonth === endMonth + ? `${startMonth} ${year}` + : `${startMonth}-${endMonth} ${year}`; + })()} + + {Current_view == "Day" && + dayjs().add(dateOffset, "day").format("DD MMMM YYYY")} +

+ +
+ +
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/DailyView.tsx b/src/components/Calendar/CalenderComponent/DailyView.tsx index 6e6a4f1f..98e20082 100644 --- a/src/components/Calendar/CalenderComponent/DailyView.tsx +++ b/src/components/Calendar/CalenderComponent/DailyView.tsx @@ -1,118 +1,118 @@ -import React, { useState, useContext, useEffect } from "react"; -import dayjs from "dayjs"; -import GlobalContext from "../context/GlobalContext"; -import { time_list } from "./WeekDay"; -import { selectedDayEvent } from "../context/GlobalContext"; -import { labelsClasses } from "../context/ContextWrapper"; - -interface Event { - startDateTime: any; - endDateTime: any; - rowIdx: any; -} - -let colors = - "border-green-400 border-red-400 border-indigo-400 border-gray-400 border-blue-400 border-purple-400"; -let hover_colors = - "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; -let text_colors = - "text-green-400 text--red-400 text-indigo-400 text-gray-400 text-blue-300 text-purple-400"; - -export default function DailyView({ date }: { date: any }) { - const [dayEvents, setDayEvents] = useState([]); - const { - setShowEventModal, - setDaySelected, - filteredEvents, - setSelectedEvent, - setTimeFrom, - setTimeTo, - } = useContext(GlobalContext); - - useEffect(() => { - const events = filteredEvents.filter( - (evt: Event) => - dayjs(evt.startDateTime).format("DD-MM-YY") === date.format("DD-MM-YY"), - ); - setDayEvents(events); - }, [filteredEvents, date]); - - function getCurrentDate() { - return date.format("DD-MM-YY") === dayjs().format("DD-MM-YY") - ? "text-white bg-blue-700 rounded-full " - : ""; - } - - function getCurrentDay() { - return date.format("DD-MM-YY") === dayjs().format("DD-MM-YY") - ? "text-blue-700" - : ""; - } - - function handleTimeSelected(time: string, i: number) { - if (time === "11:00 PM") { - setTimeFrom(time_list[i]); - setTimeTo(time_list[0]); - } else { - setTimeFrom(time_list[i]); - setTimeTo(time_list[i + 1]); - } - } - function displayColor(label: string) { - return labelsClasses.get(label); - } - - return ( -
-
-

- {date.format("ddd").toUpperCase()} -

-
-

- {date.format("DD")} -

-
-
- -
- {time_list.map((time: string, i: number) => ( -

- {time} -

- ))} -
-
- {time_list.map((time: string, i: number) => ( -
{ - setDaySelected(date); - handleTimeSelected(time, i); - }} - key={i} - className="h-14 w-full border border-gray-300" - > -
- {dayEvents.map( - (evt: selectedDayEvent, idx) => - dayjs(evt.startDateTime).format("hh:00 A") === time && ( -
{ - setSelectedEvent(evt); - setShowEventModal(true); - }} - > - {evt.job.company.name} -
- ), - )} -
-
- ))} -
-
-
- ); -} +import React, { useState, useContext, useEffect } from "react"; +import dayjs from "dayjs"; +import GlobalContext from "../context/GlobalContext"; +import { time_list } from "./WeekDay"; +import { selectedDayEvent } from "../context/GlobalContext"; +import { labelsClasses } from "../context/ContextWrapper"; + +interface Event { + startDateTime: any; + endDateTime: any; + rowIdx: any; +} + +let colors = + "border-green-400 border-red-400 border-indigo-400 border-gray-400 border-blue-400 border-purple-400"; +let hover_colors = + "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; +let text_colors = + "text-green-400 text--red-400 text-indigo-400 text-gray-400 text-blue-300 text-purple-400"; + +export default function DailyView({ date }: { date: any }) { + const [dayEvents, setDayEvents] = useState([]); + const { + setShowEventModal, + setDaySelected, + filteredEvents, + setSelectedEvent, + setTimeFrom, + setTimeTo, + } = useContext(GlobalContext); + + useEffect(() => { + const events = filteredEvents.filter( + (evt: Event) => + dayjs(evt.startDateTime).format("DD-MM-YY") === date.format("DD-MM-YY"), + ); + setDayEvents(events); + }, [filteredEvents, date]); + + function getCurrentDate() { + return date.format("DD-MM-YY") === dayjs().format("DD-MM-YY") + ? "text-white bg-blue-700 rounded-full " + : ""; + } + + function getCurrentDay() { + return date.format("DD-MM-YY") === dayjs().format("DD-MM-YY") + ? "text-blue-700" + : ""; + } + + function handleTimeSelected(time: string, i: number) { + if (time === "11:00 PM") { + setTimeFrom(time_list[i]); + setTimeTo(time_list[0]); + } else { + setTimeFrom(time_list[i]); + setTimeTo(time_list[i + 1]); + } + } + function displayColor(label: string) { + return labelsClasses.get(label); + } + + return ( +
+
+

+ {date.format("ddd").toUpperCase()} +

+
+

+ {date.format("DD")} +

+
+
+ +
+ {time_list.map((time: string, i: number) => ( +

+ {time} +

+ ))} +
+
+ {time_list.map((time: string, i: number) => ( +
{ + setDaySelected(date); + handleTimeSelected(time, i); + }} + key={i} + className="h-14 w-full border border-gray-300" + > +
+ {dayEvents.map( + (evt: selectedDayEvent, idx) => + dayjs(evt.startDateTime).format("hh:00 A") === time && ( +
{ + setSelectedEvent(evt); + setShowEventModal(true); + }} + > + {evt.job.company.name} +
+ ), + )} +
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/EventDetails.tsx b/src/components/Calendar/CalenderComponent/EventDetails.tsx index 150ec7d8..28e75cee 100644 --- a/src/components/Calendar/CalenderComponent/EventDetails.tsx +++ b/src/components/Calendar/CalenderComponent/EventDetails.tsx @@ -1,142 +1,142 @@ -import React, { useContext, useState } from "react"; -import GlobalContext from "../context/GlobalContext"; -import dayjs from "dayjs"; -import { labelsClasses } from "../context/ContextWrapper"; - -export default function EventDetails() { - const { setShowEventModal, daySelected, selectedEvent } = - useContext(GlobalContext); - - const [description, setDescription] = useState( - selectedEvent ? selectedEvent.metadata : "", - ); - const [selectedLabel, setSelectedLabel] = useState<[string, string]>( - selectedEvent - ? [selectedEvent.type, labelsClasses.get(selectedEvent.type) || ""] - : ["", ""], - ); - const [timeFrom, setTimeFrom] = useState( - selectedEvent - ? dayjs(selectedEvent.startDateTime).format("hh:00 A") - : "from", - ); - const [timeTo, setTimeTo] = useState( - selectedEvent ? dayjs(selectedEvent.endDateTime).format("hh:00 A") : "to", - ); - const [checked, setChecked] = useState( - selectedEvent ? selectedEvent.visibleToRecruiter : false, - ); - const [companyName, setCompanyName] = useState( - selectedEvent ? selectedEvent.job.company.name : "", - ); - const [role, setRole] = useState(selectedEvent ? selectedEvent.job.role : ""); - const [recruitmentType, setRecruitmentType] = useState( - selectedEvent ? selectedEvent.job.season.type : "", - ); - const [roundNumber, setRoundNumber] = useState( - selectedEvent ? selectedEvent.roundNumber : 1, - ); - - function visibilityStatus(check: boolean) { - return check ? "Yes" : "No"; - } - - return ( -
-
-
- - drag_handle - - -
-
-
- - schedule - -

- {daySelected.format("dddd, MMMM DD")} -

-
-
-

- {timeFrom} -

-
-

-

-
-

- {timeTo} -

-
-
- {description && ( - - segment - - )} - - {description && ( - - {description} - - )} - - visibility - - - Visible to Recruiter : - - - {visibilityStatus(checked)} - - - label - -
- - {selectedLabel[0]} - -
- - - work - -
Type :
- - - {recruitmentType} - - -
Company :
- - {companyName} - -
Role :
- - - {role} - -
Round :
- - - {roundNumber} - -
-
-
-
-
- ); -} +import React, { useContext, useState } from "react"; +import GlobalContext from "../context/GlobalContext"; +import dayjs from "dayjs"; +import { labelsClasses } from "../context/ContextWrapper"; + +export default function EventDetails() { + const { setShowEventModal, daySelected, selectedEvent } = + useContext(GlobalContext); + + const [description, setDescription] = useState( + selectedEvent ? selectedEvent.metadata : "", + ); + const [selectedLabel, setSelectedLabel] = useState<[string, string]>( + selectedEvent + ? [selectedEvent.type, labelsClasses.get(selectedEvent.type) || ""] + : ["", ""], + ); + const [timeFrom, setTimeFrom] = useState( + selectedEvent + ? dayjs(selectedEvent.startDateTime).format("hh:00 A") + : "from", + ); + const [timeTo, setTimeTo] = useState( + selectedEvent ? dayjs(selectedEvent.endDateTime).format("hh:00 A") : "to", + ); + const [checked, setChecked] = useState( + selectedEvent ? selectedEvent.visibleToRecruiter : false, + ); + const [companyName, setCompanyName] = useState( + selectedEvent ? selectedEvent.job.company.name : "", + ); + const [role, setRole] = useState(selectedEvent ? selectedEvent.job.role : ""); + const [recruitmentType, setRecruitmentType] = useState( + selectedEvent ? selectedEvent.job.season.type : "", + ); + const [roundNumber, setRoundNumber] = useState( + selectedEvent ? selectedEvent.roundNumber : 1, + ); + + function visibilityStatus(check: boolean) { + return check ? "Yes" : "No"; + } + + return ( +
+
+
+ + drag_handle + + +
+
+
+ + schedule + +

+ {daySelected.format("dddd, MMMM DD")} +

+
+
+

+ {timeFrom} +

+
+

-

+
+

+ {timeTo} +

+
+
+ {description && ( + + segment + + )} + + {description && ( + + {description} + + )} + + visibility + + + Visible to Recruiter : + + + {visibilityStatus(checked)} + + + label + +
+ + {selectedLabel[0]} + +
+ + + work + +
Type :
+ + + {recruitmentType} + + +
Company :
+ + {companyName} + +
Role :
+ + + {role} + +
Round :
+ + + {roundNumber} + +
+
+
+
+
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/Labels.tsx b/src/components/Calendar/CalenderComponent/Labels.tsx index 293bfe96..b19e3ac1 100644 --- a/src/components/Calendar/CalenderComponent/Labels.tsx +++ b/src/components/Calendar/CalenderComponent/Labels.tsx @@ -1,32 +1,32 @@ -import React, { useContext } from "react"; -import GlobalContext from "../context/GlobalContext"; -import { labelsClasses } from "../context/ContextWrapper"; - -let colors = - "text-green-400 text-red-400 text-indigo-400 text-gray-400 text-blue-400 text-purple-400"; -export default function Labels() { - const { labels, updateLabel } = useContext(GlobalContext); - - return ( - -

Label

- {Array.from(labelsClasses.entries()).map(([label, color], idx) => { - const checked = - labels.find((lbl) => lbl.label === label)?.checked || false; - return ( - - ); - })} -
- ); -} +import React, { useContext } from "react"; +import GlobalContext from "../context/GlobalContext"; +import { labelsClasses } from "../context/ContextWrapper"; + +let colors = + "text-green-400 text-red-400 text-indigo-400 text-gray-400 text-blue-400 text-purple-400"; +export default function Labels() { + const { labels, updateLabel } = useContext(GlobalContext); + + return ( + +

Label

+ {Array.from(labelsClasses.entries()).map(([label, color], idx) => { + const checked = + labels.find((lbl) => lbl.label === label)?.checked || false; + return ( + + ); + })} +
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/Month.tsx b/src/components/Calendar/CalenderComponent/Month.tsx index 1d7c2f71..59db3434 100644 --- a/src/components/Calendar/CalenderComponent/Month.tsx +++ b/src/components/Calendar/CalenderComponent/Month.tsx @@ -1,16 +1,16 @@ -import React from "react"; -import Day from "./MonthDay"; - -export default function Month({ month }: { month: any }) { - return ( -
- {month.map((row: any[], i: any) => ( - - {row.map((day, idx) => ( - - ))} - - ))} -
- ); -} +import React from "react"; +import Day from "./MonthDay"; + +export default function Month({ month }: { month: any }) { + return ( +
+ {month.map((row: any[], i: any) => ( + + {row.map((day, idx) => ( + + ))} + + ))} +
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/MonthDay.tsx b/src/components/Calendar/CalenderComponent/MonthDay.tsx index c91851ef..01c7f970 100644 --- a/src/components/Calendar/CalenderComponent/MonthDay.tsx +++ b/src/components/Calendar/CalenderComponent/MonthDay.tsx @@ -1,92 +1,92 @@ -import React, { useContext, useEffect, useState } from "react"; -import dayjs from "dayjs"; -import GlobalContext from "../context/GlobalContext"; -import { selectedDayEvent } from "../context/GlobalContext"; -import { labelsClasses } from "../context/ContextWrapper"; - -interface Event { - startDateTime: any; - endDateTime: any; - rowIdx: any; -} - -let colors = - "bg-green-300 bg-red-300 bg-indigo-300 bg-gray-300 bg-blue-300 bg-purple-300"; -let hover_colors = - "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; - -export default function Day({ day, rowIdx }: { day: any; rowIdx: any }) { - const [dayEvents, setDayEvents] = useState([]); - const { - setShowEventModal, - setDaySelected, - setSelectedEvent, - monthIndex, - filteredEvents, - } = useContext(GlobalContext); - - useEffect(() => { - const events = filteredEvents.filter( - (evt: Event) => - dayjs(evt.startDateTime).format("DD-MM-YY") === day.format("DD-MM-YY"), - ); - setDayEvents(events); - }, [filteredEvents, day]); - - function getCurrentDay() { - return day.format("DD-MM-YY") === dayjs().format("DD-MM-YY") - ? "bg-blue-700 text-white rounded-full w-7" - : ""; - } - function getCurrentMonth() { - return parseInt(day.format("MM"), 10) === monthIndex + 1 - ? "" - : "opacity-50"; - } - - function displayColor(label: string) { - return labelsClasses.get(label); - } - - return ( -
-
- {rowIdx === 0 && ( -

{day.format("ddd").toUpperCase()}

- )} - -

{ - setDaySelected(day); - }} - className={`text-sm p-1 my-1 font-semibold text-center hover:cursor-pointer hover:bg-slate-300 hover:rounded-full hover:text-black ${getCurrentDay()} ${getCurrentMonth()}`} - > - {parseInt(day.format("DD"), 10) === 1 - ? day.format("MMM DD") - : day.format("DD")} -

-
-
{ - setDaySelected(day); - }} - className="flex-1 overflow-y-auto" - > - {dayEvents.map((evt: selectedDayEvent, idx) => ( -
{ - setSelectedEvent(evt); - setShowEventModal(true); - }} - key={idx} - className={`bg-${displayColor(evt.type)}-300 hover:bg-${displayColor(evt.type)}-400 ${getCurrentMonth()} event_block cursor-pointer p-1 mx-2 text-gray-600 text-sm rounded mb-1 truncate`} - > - {evt.job && evt.job.company && evt.job.company.name - ? evt.job.company.name - : evt.id} -
- ))} -
-
- ); -} +import React, { useContext, useEffect, useState } from "react"; +import dayjs from "dayjs"; +import GlobalContext from "../context/GlobalContext"; +import { selectedDayEvent } from "../context/GlobalContext"; +import { labelsClasses } from "../context/ContextWrapper"; + +interface Event { + startDateTime: any; + endDateTime: any; + rowIdx: any; +} + +let colors = + "bg-green-300 bg-red-300 bg-indigo-300 bg-gray-300 bg-blue-300 bg-purple-300"; +let hover_colors = + "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; + +export default function Day({ day, rowIdx }: { day: any; rowIdx: any }) { + const [dayEvents, setDayEvents] = useState([]); + const { + setShowEventModal, + setDaySelected, + setSelectedEvent, + monthIndex, + filteredEvents, + } = useContext(GlobalContext); + + useEffect(() => { + const events = filteredEvents.filter( + (evt: Event) => + dayjs(evt.startDateTime).format("DD-MM-YY") === day.format("DD-MM-YY"), + ); + setDayEvents(events); + }, [filteredEvents, day]); + + function getCurrentDay() { + return day.format("DD-MM-YY") === dayjs().format("DD-MM-YY") + ? "bg-blue-700 text-white rounded-full w-7" + : ""; + } + function getCurrentMonth() { + return parseInt(day.format("MM"), 10) === monthIndex + 1 + ? "" + : "opacity-50"; + } + + function displayColor(label: string) { + return labelsClasses.get(label); + } + + return ( +
+
+ {rowIdx === 0 && ( +

{day.format("ddd").toUpperCase()}

+ )} + +

{ + setDaySelected(day); + }} + className={`text-sm p-1 my-1 font-semibold text-center hover:cursor-pointer hover:bg-slate-300 hover:rounded-full hover:text-black ${getCurrentDay()} ${getCurrentMonth()}`} + > + {parseInt(day.format("DD"), 10) === 1 + ? day.format("MMM DD") + : day.format("DD")} +

+
+
{ + setDaySelected(day); + }} + className="flex-1 overflow-y-auto" + > + {dayEvents.map((evt: selectedDayEvent, idx) => ( +
{ + setSelectedEvent(evt); + setShowEventModal(true); + }} + key={idx} + className={`bg-${displayColor(evt.type)}-300 hover:bg-${displayColor(evt.type)}-400 ${getCurrentMonth()} event_block cursor-pointer p-1 mx-2 text-gray-600 text-sm rounded mb-1 truncate`} + > + {evt.job && evt.job.company && evt.job.company.name + ? evt.job.company.name + : evt.id} +
+ ))} +
+
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/SidebarCalendar.tsx b/src/components/Calendar/CalenderComponent/SidebarCalendar.tsx index 91079d6e..3bd2a860 100644 --- a/src/components/Calendar/CalenderComponent/SidebarCalendar.tsx +++ b/src/components/Calendar/CalenderComponent/SidebarCalendar.tsx @@ -1,10 +1,10 @@ -import React from "react"; -import Labels from "./Labels"; - -export default function SidebarCalendar() { - return ( - - ); -} +import React from "react"; +import Labels from "./Labels"; + +export default function SidebarCalendar() { + return ( + + ); +} diff --git a/src/components/Calendar/CalenderComponent/WeekDay.tsx b/src/components/Calendar/CalenderComponent/WeekDay.tsx index 77d3936e..7877fcad 100644 --- a/src/components/Calendar/CalenderComponent/WeekDay.tsx +++ b/src/components/Calendar/CalenderComponent/WeekDay.tsx @@ -1,132 +1,132 @@ -import React, { useContext, useEffect, useState } from "react"; -import dayjs from "dayjs"; -import GlobalContext from "../context/GlobalContext"; -import { selectedDayEvent } from "../context/GlobalContext"; -import { labelsClasses } from "../context/ContextWrapper"; - -const generateTimeList = () => { - const times = []; - const format = "hh:mm A"; - - for (let hour = 0; hour < 24; hour++) { - const time = dayjs().hour(hour).minute(0).second(0); - times.push(time.format(format)); - } - - return times; -}; - -export let time_list = generateTimeList(); - -let colors = - "border-green-400 border-red-400 border-indigo-400 border-gray-400 border-blue-400 border-purple-400"; -let hover_colors = - "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; -let text_colors = - "text-green-400 text--red-400 text-indigo-400 text-gray-400 text-blue-300 text-purple-400"; - -interface Event { - startDateTime: any; - endDateTime: any; - rowIdx: any; -} - -export default function WeekDay({ day }: { day: any }) { - const [dayEvents, setDayEvents] = useState([]); - const { - setShowEventModal, - setDaySelected, - filteredEvents, - setSelectedEvent, - setTimeFrom, - setTimeTo, - } = useContext(GlobalContext); - - useEffect(() => { - const events = filteredEvents.filter( - (evt: Event) => - dayjs(evt.startDateTime).format("DD-MM-YY") === day.format("DD-MM-YY"), - ); - setDayEvents(events); - }, [filteredEvents, day]); - - function getCurrentDay() { - return day.format("DD-MM-YY") === dayjs().format("DD-MM-YY") - ? "bg-blue-700 text-white rounded-full w-10" - : ""; - } - function handleTimeSelected(time: string, i: number) { - if (time === "11:00 PM") { - setTimeFrom(time_list[i]); - setTimeTo(time_list[0]); - } else { - setTimeFrom(time_list[i]); - setTimeTo(time_list[i + 1]); - } - } - function displayColor(label: string) { - return labelsClasses.get(label); - } - - return ( -
-
-
-

- {day.format("ddd").toUpperCase()} -

-

- {day.format("DD")} -

-
-
- -
- {day.format("ddd").toUpperCase() === "SUN" && ( -
- {time_list.map((time: string, i: number) => ( -

- {time.substring(0, 2) + " " + time.substring(time.length - 2)} -

- ))} -
- )} -
- {time_list.map((time: string, i: number) => ( -
{ - setDaySelected(day); - handleTimeSelected(time, i); - }} - > -
- {dayEvents.map( - (evt: selectedDayEvent, idx) => - dayjs(evt.startDateTime).format("hh:00 A") === time && ( -
{ - setSelectedEvent(evt); - setShowEventModal(true); - }} - > - {evt.job.company.name} -
- ), - )} -
-
- ))} -
-
-
- ); -} +import React, { useContext, useEffect, useState } from "react"; +import dayjs from "dayjs"; +import GlobalContext from "../context/GlobalContext"; +import { selectedDayEvent } from "../context/GlobalContext"; +import { labelsClasses } from "../context/ContextWrapper"; + +const generateTimeList = () => { + const times = []; + const format = "hh:mm A"; + + for (let hour = 0; hour < 24; hour++) { + const time = dayjs().hour(hour).minute(0).second(0); + times.push(time.format(format)); + } + + return times; +}; + +export let time_list = generateTimeList(); + +let colors = + "border-green-400 border-red-400 border-indigo-400 border-gray-400 border-blue-400 border-purple-400"; +let hover_colors = + "hover:bg-green-400 hover:bg-red-400 hover:bg-indigo-400 hover:bg-gray-400 hover:bg-blue-400 hover:bg-purple-400"; +let text_colors = + "text-green-400 text--red-400 text-indigo-400 text-gray-400 text-blue-300 text-purple-400"; + +interface Event { + startDateTime: any; + endDateTime: any; + rowIdx: any; +} + +export default function WeekDay({ day }: { day: any }) { + const [dayEvents, setDayEvents] = useState([]); + const { + setShowEventModal, + setDaySelected, + filteredEvents, + setSelectedEvent, + setTimeFrom, + setTimeTo, + } = useContext(GlobalContext); + + useEffect(() => { + const events = filteredEvents.filter( + (evt: Event) => + dayjs(evt.startDateTime).format("DD-MM-YY") === day.format("DD-MM-YY"), + ); + setDayEvents(events); + }, [filteredEvents, day]); + + function getCurrentDay() { + return day.format("DD-MM-YY") === dayjs().format("DD-MM-YY") + ? "bg-blue-700 text-white rounded-full w-10" + : ""; + } + function handleTimeSelected(time: string, i: number) { + if (time === "11:00 PM") { + setTimeFrom(time_list[i]); + setTimeTo(time_list[0]); + } else { + setTimeFrom(time_list[i]); + setTimeTo(time_list[i + 1]); + } + } + function displayColor(label: string) { + return labelsClasses.get(label); + } + + return ( +
+
+
+

+ {day.format("ddd").toUpperCase()} +

+

+ {day.format("DD")} +

+
+
+ +
+ {day.format("ddd").toUpperCase() === "SUN" && ( +
+ {time_list.map((time: string, i: number) => ( +

+ {time.substring(0, 2) + " " + time.substring(time.length - 2)} +

+ ))} +
+ )} +
+ {time_list.map((time: string, i: number) => ( +
{ + setDaySelected(day); + handleTimeSelected(time, i); + }} + > +
+ {dayEvents.map( + (evt: selectedDayEvent, idx) => + dayjs(evt.startDateTime).format("hh:00 A") === time && ( +
{ + setSelectedEvent(evt); + setShowEventModal(true); + }} + > + {evt.job.company.name} +
+ ), + )} +
+
+ ))} +
+
+
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/WeeklyView.tsx b/src/components/Calendar/CalenderComponent/WeeklyView.tsx index aea05c81..80f1c4c9 100644 --- a/src/components/Calendar/CalenderComponent/WeeklyView.tsx +++ b/src/components/Calendar/CalenderComponent/WeeklyView.tsx @@ -1,12 +1,12 @@ -import React from "react"; -import WeekDay from "./WeekDay"; - -export default function WeeklyView({ week }: { week: any }) { - return ( -
- {week.map((day: any, i: number) => ( - - ))} -
- ); -} +import React from "react"; +import WeekDay from "./WeekDay"; + +export default function WeeklyView({ week }: { week: any }) { + return ( +
+ {week.map((day: any, i: number) => ( + + ))} +
+ ); +} diff --git a/src/components/Calendar/CalenderComponent/util.tsx b/src/components/Calendar/CalenderComponent/util.tsx index de621cad..5acc7001 100644 --- a/src/components/Calendar/CalenderComponent/util.tsx +++ b/src/components/Calendar/CalenderComponent/util.tsx @@ -1,35 +1,35 @@ -import dayjs from "dayjs"; - -export function getMonth(month = dayjs().month()) { - month = Math.floor(month); - const year = dayjs().year(); - const firstDayOfTheMonth = dayjs(new Date(year, month, 1)).day(); - let currentMonthCount = 0 - firstDayOfTheMonth; - const daysMatrix = new Array(5).fill([]).map(() => { - return new Array(7).fill(null).map(() => { - currentMonthCount++; - return dayjs(new Date(year, month, currentMonthCount)); - }); - }); - return daysMatrix; -} - -export function getWeek(weekOffset: number): dayjs.Dayjs[] { - const dates: dayjs.Dayjs[] = []; - - const today = dayjs(); - const dayOfWeek = today.day(); - let diff = today.date() - dayOfWeek + weekOffset * 7; - const sunday = dayjs().date(diff); - - for (let i = 0; i < 7; i++) { - const currentDate = dayjs(sunday).add(i, "day"); - dates.push(currentDate); - } - return dates; -} - -export function getDate(dateOffset: number): dayjs.Dayjs { - const today = dayjs(); - return today.add(dateOffset, "day"); -} +import dayjs from "dayjs"; + +export function getMonth(month = dayjs().month()) { + month = Math.floor(month); + const year = dayjs().year(); + const firstDayOfTheMonth = dayjs(new Date(year, month, 1)).day(); + let currentMonthCount = 0 - firstDayOfTheMonth; + const daysMatrix = new Array(5).fill([]).map(() => { + return new Array(7).fill(null).map(() => { + currentMonthCount++; + return dayjs(new Date(year, month, currentMonthCount)); + }); + }); + return daysMatrix; +} + +export function getWeek(weekOffset: number): dayjs.Dayjs[] { + const dates: dayjs.Dayjs[] = []; + + const today = dayjs(); + const dayOfWeek = today.day(); + let diff = today.date() - dayOfWeek + weekOffset * 7; + const sunday = dayjs().date(diff); + + for (let i = 0; i < 7; i++) { + const currentDate = dayjs(sunday).add(i, "day"); + dates.push(currentDate); + } + return dates; +} + +export function getDate(dateOffset: number): dayjs.Dayjs { + const today = dayjs(); + return today.add(dateOffset, "day"); +} diff --git a/src/components/Calendar/context/ContextWrapper.tsx b/src/components/Calendar/context/ContextWrapper.tsx index 338ecdb8..3056f105 100644 --- a/src/components/Calendar/context/ContextWrapper.tsx +++ b/src/components/Calendar/context/ContextWrapper.tsx @@ -1,150 +1,150 @@ -import React, { useState, useReducer, useEffect, useMemo } from "react"; -import dayjs from "dayjs"; -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"], - ["PPT", "red"], - ["TEST", "indigo"], - ["COMPLETED", "blue"], - ["APPLICATION", "purple"], -]); - -function savedEventsReducer( - state: selectedDayEvent[], - { type, payload }: { type: string; payload: any }, -) { - switch (type) { - case "fetch": - return payload; - default: - throw new Error(); - } -} - -export default function ContextWrapper(props: any) { - const [monthIndex, setMonthIndex] = useState(dayjs().month()); - const [weekOffset, setWeekOffset] = useState(0); - const [dateOffset, setDateOffset] = useState(0); - const [Current_view, SetCurrent_view] = useState("Month"); - const [showEventModal, setShowEventModal] = useState(false); - const [daySelected, setDaySelected] = useState(dayjs()); - const [selectedEvent, setSelectedEvent] = useState( - null, - ); - const [labels, setLabels] = useState(() => { - return Array.from(labelsClasses.keys()).map((label) => ({ - label, - checked: true, - })); - }); - const [savedEvents, dispatchCallEvents] = useReducer(savedEventsReducer, []); - const [timeFrom, setTimeFrom] = useState("from"); - const [timeTo, setTimeTo] = useState("to"); - - const filteredEvents = useMemo(() => { - return savedEvents.filter((evt: selectedDayEvent) => - labels - .filter((lbl) => lbl.checked) - .map((lbl) => lbl.label) - .includes(evt.type), - ); - }, [savedEvents, labels]); - - useEffect(() => { - async function fetchAndSetEvents() { - try { - 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(); - }, []); - - useEffect(() => { - setLabels((prevLabels) => { - const uniqueEventTypes = [...new Set(savedEvents.map((evt) => evt.type))]; - - return uniqueEventTypes.map((label: string) => { - const currentLabel = prevLabels.find((lbl) => lbl.label === label); - return { - label: label, - checked: currentLabel ? currentLabel.checked : true, - }; - }); - }); - }, [savedEvents]); - - function updateLabel(newLabel: { label: string; checked: boolean }) { - setLabels((prevLabels) => - prevLabels.map((lbl) => (lbl.label === newLabel.label ? newLabel : lbl)), - ); - } - - return ( - - {props.children} - - ); -} +import React, { useState, useReducer, useEffect, useMemo } from "react"; +import dayjs from "dayjs"; +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 { jwtDecode } from "jwt-decode"; +import { fetchStudentEvents } from "@/helpers/student/api"; + +export const labelsClasses = new Map([ + ["INTERVIEW", "green"], + ["PPT", "red"], + ["TEST", "indigo"], + ["COMPLETED", "blue"], + ["APPLICATION", "purple"], +]); + +function savedEventsReducer( + state: selectedDayEvent[], + { type, payload }: { type: string; payload: any }, +) { + switch (type) { + case "fetch": + return payload; + default: + throw new Error(); + } +} + +export default function ContextWrapper(props: any) { + const [monthIndex, setMonthIndex] = useState(dayjs().month()); + const [weekOffset, setWeekOffset] = useState(0); + const [dateOffset, setDateOffset] = useState(0); + const [Current_view, SetCurrent_view] = useState("Month"); + const [showEventModal, setShowEventModal] = useState(false); + const [daySelected, setDaySelected] = useState(dayjs()); + const [selectedEvent, setSelectedEvent] = useState( + null, + ); + const [labels, setLabels] = useState(() => { + return Array.from(labelsClasses.keys()).map((label) => ({ + label, + checked: true, + })); + }); + const [savedEvents, dispatchCallEvents] = useReducer(savedEventsReducer, []); + const [timeFrom, setTimeFrom] = useState("from"); + const [timeTo, setTimeTo] = useState("to"); + + const filteredEvents = useMemo(() => { + return savedEvents.filter((evt: selectedDayEvent) => + labels + .filter((lbl) => lbl.checked) + .map((lbl) => lbl.label) + .includes(evt.type), + ); + }, [savedEvents, labels]); + + useEffect(() => { + async function fetchAndSetEvents() { + try { + const accessToken = Cookies.get("accessToken"); + let user = null; + + if (accessToken) { + try { + const decoded: any = jwtDecode(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(); + }, []); + + useEffect(() => { + setLabels((prevLabels) => { + const uniqueEventTypes = [...new Set(savedEvents.map((evt) => evt.type))]; + + return uniqueEventTypes.map((label: string) => { + const currentLabel = prevLabels.find((lbl) => lbl.label === label); + return { + label: label, + checked: currentLabel ? currentLabel.checked : true, + }; + }); + }); + }, [savedEvents]); + + function updateLabel(newLabel: { label: string; checked: boolean }) { + setLabels((prevLabels) => + prevLabels.map((lbl) => (lbl.label === newLabel.label ? newLabel : lbl)), + ); + } + + return ( + + {props.children} + + ); +} diff --git a/src/components/Calendar/context/GlobalContext.tsx b/src/components/Calendar/context/GlobalContext.tsx index af184019..ec96d59f 100644 --- a/src/components/Calendar/context/GlobalContext.tsx +++ b/src/components/Calendar/context/GlobalContext.tsx @@ -1,65 +1,65 @@ -import React from "react"; -import dayjs, { Dayjs } from "dayjs"; -export interface DispatchCallEventsAction { - type: string; - payload: any; -} - -export interface updateLabelAction { - label: string; - checked: boolean; -} - -export interface Job { - id: string; - role: string; - company: { - id: string; - name: string; - }; - season: { - id: string; - type: string; - year: number; - }; -} - -export interface selectedDayEvent { - id: string; - startDateTime: Date; - endDateTime: Date; - metadata: string; - roundNumber: number; - type: string; - visibleToRecruiter: boolean; - job: Job; -} - -const GlobalContext = React.createContext({ - monthIndex: 0, - setMonthIndex: (index: number) => {}, - weekOffset: 0, - setWeekOffset: (index: number) => {}, - dateOffset: 0, - setDateOffset: (index: number) => {}, - Current_view: "", - SetCurrent_view: (view: string) => {}, - showEventModal: false, - setShowEventModal: (setBool: boolean) => {}, - daySelected: null as Dayjs | null, - setDaySelected: (day: Dayjs) => {}, - dispatchCallEvents: (action: DispatchCallEventsAction) => {}, - savedEvents: [], - selectedEvent: null as selectedDayEvent | null, - setSelectedEvent: (event: selectedDayEvent | null) => {}, - setLabels: (newLabels: updateLabelAction[]) => {}, - labels: [] as updateLabelAction[], - updateLabel: (action: updateLabelAction) => {}, - filteredEvents: [], - timeFrom: null as string | null, - setTimeFrom: (time: string) => {}, - timeTo: null as string | null, - setTimeTo: (time: string) => {}, -}); - -export default GlobalContext; +import React from "react"; +import dayjs, { Dayjs } from "dayjs"; +export interface DispatchCallEventsAction { + type: string; + payload: any; +} + +export interface updateLabelAction { + label: string; + checked: boolean; +} + +export interface Job { + id: string; + role: string; + company: { + id: string; + name: string; + }; + season: { + id: string; + type: string; + year: number; + }; +} + +export interface selectedDayEvent { + id: string; + startDateTime: Date; + endDateTime: Date; + metadata: string; + roundNumber: number; + type: string; + visibleToRecruiter: boolean; + job: Job; +} + +const GlobalContext = React.createContext({ + monthIndex: 0, + setMonthIndex: (index: number) => {}, + weekOffset: 0, + setWeekOffset: (index: number) => {}, + dateOffset: 0, + setDateOffset: (index: number) => {}, + Current_view: "", + SetCurrent_view: (view: string) => {}, + showEventModal: false, + setShowEventModal: (setBool: boolean) => {}, + daySelected: null as Dayjs | null, + setDaySelected: (day: Dayjs) => {}, + dispatchCallEvents: (action: DispatchCallEventsAction) => {}, + savedEvents: [], + selectedEvent: null as selectedDayEvent | null, + setSelectedEvent: (event: selectedDayEvent | null) => {}, + setLabels: (newLabels: updateLabelAction[]) => {}, + labels: [] as updateLabelAction[], + updateLabel: (action: updateLabelAction) => {}, + filteredEvents: [], + timeFrom: null as string | null, + setTimeFrom: (time: string) => {}, + timeTo: null as string | null, + setTimeTo: (time: string) => {}, +}); + +export default GlobalContext; diff --git a/src/components/Faculty/FeedbackFrom.tsx b/src/components/Faculty/FeedbackFrom.tsx index f470025b..aefbe9d1 100644 --- a/src/components/Faculty/FeedbackFrom.tsx +++ b/src/components/Faculty/FeedbackFrom.tsx @@ -1,159 +1,159 @@ -import { - Dialog, - DialogContent, - DialogTrigger, - DialogClose, -} from "../ui/dialog"; -import TextArea from "antd/es/input/TextArea"; -import { Button } from "@/components/ui/button"; -import { useState, useEffect } from "react"; -import { updateApproval } from "@/helpers//faculty/api"; -import tick from "@/../public/tick.svg"; -import cross from "@/../public/cross.svg"; - -interface ButtonProps { - children?: React.ReactNode; - rows?: any[]; - remarks?: string; - finalButton: boolean; -} - -const UpdateApprovalPATCH = (rows: any[], remarks: string, status: string) => { - for (var i = 0; i < rows.length; i++) { - updateApproval({ - id: rows[i].id, - remarks: remarks, - status: status, - }); - } - window.location.reload(); -}; - -const AcceptButton: React.FC = ({ - rows = [], - remarks = "", - finalButton, -}) => { - return ( - - ); -}; - -const RejectButton: React.FC = ({ - rows = [], - remarks = "", - finalButton, -}) => { - return ( - - ); -}; - -interface Props { - checkedRows: any[]; // Define the prop type as an array of any type -} - -const FeedbackForm: React.FC = ({ checkedRows }) => { - const [isClient, setIsClient] = useState(false); - - useEffect(() => { - setIsClient(true); - }, []); - - const [feedbackText, setFeedbackText] = useState(""); - - return ( - <> -

Write Feedback

-