From 4d79a32e69ed6267a4da76c474b901526dba4ef9 Mon Sep 17 00:00:00 2001 From: AryanGKulkarni <95529889+AryanGKulkarni@users.noreply.github.com> Date: Sat, 15 Jun 2024 00:58:47 +0530 Subject: [PATCH 1/5] job page added --- .../student/{jobs => job}/[jobId]/page.tsx | 2 +- .../{jobs => job}/salary/[jobId]/page.tsx | 23 +-- src/app/(routes)/student/jobs/page.tsx | 45 +++++ src/app/(routes)/student/onCampus/page.tsx | 18 +- src/components/jobs/JobCard.tsx | 114 +++--------- src/components/jobs/OnCampusCard.tsx | 176 ++++++++++++++++++ src/components/jobs/SalaryCard.tsx | 55 +++++- src/helpers/student/api.ts | 12 ++ src/helpers/student/types.ts | 41 +++- 9 files changed, 358 insertions(+), 128 deletions(-) rename src/app/(routes)/student/{jobs => job}/[jobId]/page.tsx (98%) rename src/app/(routes)/student/{jobs => job}/salary/[jobId]/page.tsx (76%) create mode 100644 src/app/(routes)/student/jobs/page.tsx create mode 100644 src/components/jobs/OnCampusCard.tsx diff --git a/src/app/(routes)/student/jobs/[jobId]/page.tsx b/src/app/(routes)/student/job/[jobId]/page.tsx similarity index 98% rename from src/app/(routes)/student/jobs/[jobId]/page.tsx rename to src/app/(routes)/student/job/[jobId]/page.tsx index 3cdd18da..f154d091 100644 --- a/src/app/(routes)/student/jobs/[jobId]/page.tsx +++ b/src/app/(routes)/student/job/[jobId]/page.tsx @@ -209,7 +209,7 @@ const JobPage = ({ params }: { params: { jobId: string } }) => {
diff --git a/src/app/(routes)/student/jobs/salary/[jobId]/page.tsx b/src/app/(routes)/student/job/salary/[jobId]/page.tsx similarity index 76% rename from src/app/(routes)/student/jobs/salary/[jobId]/page.tsx rename to src/app/(routes)/student/job/salary/[jobId]/page.tsx index f800c79a..652de646 100644 --- a/src/app/(routes)/student/jobs/salary/[jobId]/page.tsx +++ b/src/app/(routes)/student/job/salary/[jobId]/page.tsx @@ -1,20 +1,11 @@ "use client"; import React, { useEffect, useState } from "react"; -import { - Table, - TableHeader, - TableBody, - TableFooter, - TableHead, - TableRow, - TableCell, -} from "@/components/ui/table"; -import { SampleJobData } from "@/dummyData/job"; -import { Separator } from "@/components/ui/separator"; import SalaryCard from "@/components/jobs/SalaryCard"; -import { GetJobById } from "@/helpers/student/api"; +import Cookies from "js-cookie"; +import { GetJobById, GetResumes } from "@/helpers/student/api"; +import { Resume } from "@/helpers/student/types"; + -interface Props {} interface Salary { id: string; salaryPeriod: string; @@ -34,11 +25,15 @@ interface Salary { const SalaryPage = ({ params }: { params: { jobId: string } }) => { const [salaryData, setSalaryData] = useState([]); + const [resumes, setResumes] = useState([]); useEffect(() => { const fetchSalaryData = async () => { const data = await GetJobById(params.jobId); setSalaryData(data.salaries); + + const res = await GetResumes(Cookies.get("accessToken")); + setResumes(res); }; fetchSalaryData(); @@ -53,7 +48,7 @@ const SalaryPage = ({ params }: { params: { jobId: string } }) => {
): (salaryData.map((item,index)=>(
- +
)))}
diff --git a/src/app/(routes)/student/jobs/page.tsx b/src/app/(routes)/student/jobs/page.tsx new file mode 100644 index 00000000..a127b87a --- /dev/null +++ b/src/app/(routes)/student/jobs/page.tsx @@ -0,0 +1,45 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import JobCard from "@/components/jobs/JobCard"; +import Cookies from "js-cookie"; +import { GetJobs, GetResumes } from "@/helpers/student/api"; +import { Jobs, Resume } from "@/helpers/student/types"; + +const StudentPage = () => { + + const [jobs, setJobs] = useState([]); + const [resumes, setResumes] = useState([]) + + useEffect(() => { + const fetchJobs = async () => { + const data = await GetJobs(); + setJobs(data); + + const res = await GetResumes(Cookies.get("accessToken")); + setResumes(res); + + }; + + fetchJobs(); + // setJobs(Jobs); + }, []); + + return ( +
+
+

Apply

+
+ {jobs.length===0? ( +
+ No Jobs +
+ ): (jobs.map((job)=>( +
+ +
+ )))} +
+ ); +}; + +export default StudentPage; diff --git a/src/app/(routes)/student/onCampus/page.tsx b/src/app/(routes)/student/onCampus/page.tsx index 4c3c0f2e..27218304 100644 --- a/src/app/(routes)/student/onCampus/page.tsx +++ b/src/app/(routes)/student/onCampus/page.tsx @@ -8,40 +8,34 @@ import { Button } from "@/components/ui/button"; import Cookies from "js-cookie"; import { GetOnCampusOffers, GetResumes } from "@/helpers/student/api"; import { OnCampusOffers, Resume } from "@/helpers/student/types"; - -interface Props {} +import OnCampusCard from "@/components/jobs/OnCampusCard"; const StudentPage = () => { const [onCampusOffers, setOnCampusOffers] = useState([]); - const [resumes, setResumes] = useState([]) useEffect(() => { - const fetchJobs = async () => { + const fetchOffers = async () => { const oco = await GetOnCampusOffers(Cookies.get("accessToken")); setOnCampusOffers(oco); - const res = await GetResumes(Cookies.get("accessToken")); - setResumes(res); - }; - fetchJobs(); - // setJobs(Jobs); + fetchOffers(); }, []); return (
-

Apply

+

Offers

{onCampusOffers.length===0? (
- No Jobs + No Offers
): (onCampusOffers.map((job)=>(
- +
)))}
diff --git a/src/components/jobs/JobCard.tsx b/src/components/jobs/JobCard.tsx index f911807d..faf2f278 100644 --- a/src/components/jobs/JobCard.tsx +++ b/src/components/jobs/JobCard.tsx @@ -14,75 +14,30 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" -import { OnCampusOffers, Salary, Resume } from "@/helpers/student/types"; +import { Salary, Resume, Jobs } from "@/helpers/student/types"; import { ApplyJob, GetSalaryById } from "@/helpers/student/api"; import Cookies from "js-cookie"; import toast, { Toaster } from "react-hot-toast"; +const baseUrl = process.env.NEXT_PUBLIC_FRONTEND_URL; + +const url = (NextUrl: string) => { + return `${baseUrl}${NextUrl}`; +}; interface Props { - jobItem: OnCampusOffers; - salaryId: string; - resumes: Resume[]; + jobItem: Jobs; } -const JobCard = ({ jobItem, salaryId, resumes }: Props) => { - const [salary, setSalary] = useState(null); - - useEffect(() => { - const fetchSalary = async () => { - const data = await GetSalaryById(salaryId); - setSalary(data); - console.log(data); - }; - - fetchSalary(); - // setJobs(Jobs); - }, [salaryId]); - const [selectedResume, setSelectedResume] = useState(null); +const JobCard = ({ jobItem }: Props) => { const [showDescription, setShowDescription] = useState(false); - - const handleResumeChange = (value: string) => { - setSelectedResume(value); - }; const handleViewDetails = () => { setShowDescription(!showDescription); }; - const handleApply = async () => { - const data = await ApplyJob(Cookies.get("accessToken"),salaryId,selectedResume); - if(data.status===201){ - toast.success("Applied Successfully"); - } - else{ - toast.error("Cannot Apply"); - } - } - - const roundOff = (n: number) => { - return Math.round((n + Number.EPSILON) * 100) / 100; - }; - - function formatNumber(num: number): string { - if (num >= 1e7) { - // Convert to Crores - const crores = num / 1e7; - return `₹${crores.toFixed(2)} Crores`; - } else if (num >= 1e5) { - // Convert to Lakhs - const lakhs = num / 1e5; - return `₹${lakhs.toFixed(2)} Lakhs`; - } else { - return `₹${num.toString()}`; - } - } - return ( -
- {salary===null? ( -
No Data
- ): ( -
+
+
- {jobItem.salary.job.company.name} + {jobItem.company.name}
@@ -90,23 +45,23 @@ const JobCard = ({ jobItem, salaryId, resumes }: Props) => {
Role
{" "} -
{jobItem.salary.job.role}
+
{jobItem.role}
-
Period
{" "} -
{salary.salaryPeriod}
+
Current Status
{" "} +
{jobItem.currentStatus}
-
CTC
{" "} -
{formatNumber(salary.totalCTC)}
+
Location
{" "} +
{jobItem.location}
-
Base Salary
{" "} -
{formatNumber(salary.baseSalary)}
+
Season
{" "} +
{jobItem.season.type} {jobItem.season.year}
-
Minimum CPI
{" "} -
{roundOff(salary.minCPI)}
+
Recruiter
{" "} +
{jobItem.recruiter.user.name}
{showDescription && ( @@ -118,7 +73,7 @@ const JobCard = ({ jobItem, salaryId, resumes }: Props) => {

About The Work

- + View Details {'>'}
@@ -184,36 +139,13 @@ const JobCard = ({ jobItem, salaryId, resumes }: Props) => {
- -
)}
- )}
); }; diff --git a/src/components/jobs/OnCampusCard.tsx b/src/components/jobs/OnCampusCard.tsx new file mode 100644 index 00000000..28717508 --- /dev/null +++ b/src/components/jobs/OnCampusCard.tsx @@ -0,0 +1,176 @@ +import React from "react"; +import Link from "next/link"; +import { Separator } from "../ui/separator"; +import { fetchJobSalary } from "@/helpers/api"; +import { useState, useEffect } from 'react'; +import {JobDetails} from "@/dummyData/jobdetails" +import { Button } from "@/components/ui/button"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { OnCampusOffers, Salary, Resume } from "@/helpers/student/types"; +import { ApplyJob, GetSalaryById } from "@/helpers/student/api"; +import Cookies from "js-cookie"; +import toast, { Toaster } from "react-hot-toast"; +interface Props { + jobItem: OnCampusOffers; + salaryId: string; +} + +const OnCampusCard = ({ jobItem, salaryId }: Props) => { + const [salary, setSalary] = useState(null); + + useEffect(() => { + const fetchSalary = async () => { + const data = await GetSalaryById(salaryId); + setSalary(data); + console.log(data); + }; + + fetchSalary(); + // setJobs(Jobs); + }, [salaryId]); + const [showDescription, setShowDescription] = useState(false); + const handleViewDetails = () => { + setShowDescription(!showDescription); + }; + + const roundOff = (n: number) => { + return Math.round((n + Number.EPSILON) * 100) / 100; + }; + + function formatNumber(num: number): string { + if (num >= 1e7) { + const crores = num / 1e7; + return `₹${crores.toFixed(2)} Crores`; + } else if (num >= 1e5) { + const lakhs = num / 1e5; + return `₹${lakhs.toFixed(2)} Lakhs`; + } else { + return `₹${num.toString()}`; + } + } + + return ( +
+ {salary===null? ( +
No Data
+ ): ( +
+
+ {jobItem.salary.job.company.name} +
+
+ +
+
+
+
Role
{" "} +
{jobItem.salary.job.role}
+
+
+
Period
{" "} +
{salary.salaryPeriod}
+
+
+
CTC
{" "} +
{formatNumber(salary.totalCTC)}
+
+
+
Base Salary
{" "} +
{formatNumber(salary.baseSalary)}
+
+
+
Minimum CPI
{" "} +
{roundOff(salary.minCPI)}
+
+
+ {showDescription && ( +
+
+ +
+
+
+

About The Work

+
+ + View Details {'>'} + +
+
+
    +
  • + Build an application in Flutter and connect REST APIs to provide a + seamless experience to users +
  • +
  • + Take ownership of the application and work alongside backend and + database engineers to deliver tasks based on timeline +
  • +
  • Work with 3rd party services to integrate in app
  • +
  • + Attend daily standup calls to discuss team updates and next tasks +
  • +
+
+ +
+

Skill(s) Required

+
+
+ Algorithms +
+
+ Android +
+
+ Data Structures +
+
+ Firebase +
+
+ iOS +
+
+ Flutter +
+
+ REST API +
+
+
+ +
+

Who can apply

+
    +
  • are available for the work from home job/internship
  • +
  • + can work from 8:00 pm - 2:00 am Indian Standard Time (as the company + is based outside of India & their local work timings are 9:30 am - + 3:30 pm Eastern Standard Time) +
  • +
  • + can start the work from home job/internship between 4th Jan24 and + 8th Feb24 +
  • +
  • are available for duration of 3 months
  • +
  • have relevant skills and interests
  • +
+
+
+ )} +
+ )} +
+ ); +}; + +export default OnCampusCard; diff --git a/src/components/jobs/SalaryCard.tsx b/src/components/jobs/SalaryCard.tsx index 6c129f09..7096f1c5 100644 --- a/src/components/jobs/SalaryCard.tsx +++ b/src/components/jobs/SalaryCard.tsx @@ -11,14 +11,20 @@ import { } from "@/components/ui/table"; import { SampleJobData } from "@/dummyData/job"; import { Separator } from "@/components/ui/separator"; -import { Salary } from "@/helpers/student/types"; -import { GetSalaryById } from "@/helpers/student/api"; +import { Resume, Salary } from "@/helpers/student/types"; +import { ApplyJob, GetSalaryById } from "@/helpers/student/api"; +import { Button } from "../ui/button"; +import Link from "next/link"; +import Cookies from "js-cookie"; +import toast, { Toaster } from "react-hot-toast"; +import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../ui/select"; interface Props{ salaryId: string; + resumes: Resume[]; } -export default function SalaryCard({salaryId}: Props) { +export default function SalaryCard({salaryId, resumes}: Props) { const [salaryData, setSalaryData] = useState(null); useEffect(() => { @@ -29,6 +35,22 @@ export default function SalaryCard({salaryId}: Props) { fetchSalaryData(); }, [salaryId]); + + const [selectedResume, setSelectedResume] = useState(null); + + const handleResumeChange = (value: string) => { + setSelectedResume(value); + }; + + const handleApply = async () => { + const data = await ApplyJob(Cookies.get("accessToken"),salaryId,selectedResume); + if(data.status===201){ + toast.success("Applied Successfully"); + } + else{ + toast.error("Cannot Apply"); + } + } const [isopen, setIsopen] = useState(false); const handleViewDetails = () => { @@ -210,6 +232,33 @@ export default function SalaryCard({salaryId}: Props) {
+
+ + +
)}
diff --git a/src/helpers/student/api.ts b/src/helpers/student/api.ts index 4e751bbd..b781a2fb 100644 --- a/src/helpers/student/api.ts +++ b/src/helpers/student/api.ts @@ -17,6 +17,18 @@ export const GetJobById = async (jobId: string) => { console.error("Error fetching Job data:", error); } }; +export const GetJobs = async () => { + try { + const res = await fetch(url(`/jobs`)); + if (!res.ok) { + throw new Error("Failed to fetch Job data"); + } + const data = await res.json(); + return data; + } catch (error) { + console.error("Error fetching Job data:", error); + } +}; export const GetSalaryById = async (salaryId: string) => { try { const res = await fetch(url(`/salaries/${salaryId}`)); diff --git a/src/helpers/student/types.ts b/src/helpers/student/types.ts index 0b1dfead..247b882c 100644 --- a/src/helpers/student/types.ts +++ b/src/helpers/student/types.ts @@ -69,36 +69,36 @@ export interface Salary { season: { id: string; year: string; - type: string; // Assuming "INTERN" is a possible value, you might want to use a union type if there are more types. + type: string; }; salaries: { id: string; totalCTC: number; salaryPeriod: string; - genders: string[]; // Assuming "MALE" is a possible value, you might want to use a union type if there are more genders. + genders: string[]; programs: string[]; facultyApprovals: string[]; - categories: string[]; // Assuming "GENERAL" is a possible value, you might want to use a union type if there are more categories. + categories: string[]; minCPI: number; tenthMarks: number; twelthMarks: number; }[]; }; others: string; - genders: string[]; // Assuming "MALE" is a possible value, you might want to use a union type if there are more genders. + genders: string[]; programs: string[]; facultyApprovals: string[]; - categories: string[]; // Assuming "GENERAL" is a possible value, you might want to use a union type if there are more categories. + categories: string[]; minCPI: number; tenthMarks: number; twelthMarks: number; facultyApprovalRequests: { id: string; - status: string; // Assuming "APPROVED" is a possible value, you might want to use a union type if there are more statuses. + status: string; remarks: string; faculty: { id: string; - department: string; // Assuming "Astronomy, Astrophysics and Space Engineering" is a possible value, you might want to use a union type if there are more departments. + department: string; user: { id: string; name: string; @@ -130,6 +130,33 @@ export interface Salary { }[]; } +export interface Jobs { + id: string; + role: string; + active: boolean; + currentStatus: string; + location: string; + season: { + id: string; + year: string; + type: string; + }; + company: { + id: string; + name: string; + }; + recruiter: { + id: string; + designation: string; + user: { + id: string; + email: string; + name: string; + contact: string; + }; + }; +} + export interface Job { id: string; role: string; From 58966112d11666a60a6a9e12955ebd62ccaddca7 Mon Sep 17 00:00:00 2001 From: AryanGKulkarni <95529889+AryanGKulkarni@users.noreply.github.com> Date: Sat, 15 Jun 2024 13:19:46 +0530 Subject: [PATCH 2/5] offer page changes --- .../(routes)/recruiter/prevjaf/[jaf]/page.tsx | 2 +- src/app/(routes)/student/offCampus/page.tsx | 2 +- src/app/(routes)/student/onCampus/page.tsx | 2 +- src/components/jobs/OffCampusCard.tsx | 126 ++--------------- src/components/jobs/OnCampusCard.tsx | 130 ++++-------------- src/components/jobs/SalaryCard.tsx | 35 +++-- 6 files changed, 63 insertions(+), 234 deletions(-) diff --git a/src/app/(routes)/recruiter/prevjaf/[jaf]/page.tsx b/src/app/(routes)/recruiter/prevjaf/[jaf]/page.tsx index b0b62f8d..f29901f7 100644 --- a/src/app/(routes)/recruiter/prevjaf/[jaf]/page.tsx +++ b/src/app/(routes)/recruiter/prevjaf/[jaf]/page.tsx @@ -124,7 +124,7 @@ const JAFPage = ({ return ( <> {jafs.map((jaf,index) => ( -
+
))} diff --git a/src/app/(routes)/student/offCampus/page.tsx b/src/app/(routes)/student/offCampus/page.tsx index a3671d74..a0952d1e 100644 --- a/src/app/(routes)/student/offCampus/page.tsx +++ b/src/app/(routes)/student/offCampus/page.tsx @@ -25,7 +25,7 @@ const OffCampusPage = () => { return (
-

Apply

+

Off Campus Offers

{offCampusOffers.length===0? (
diff --git a/src/app/(routes)/student/onCampus/page.tsx b/src/app/(routes)/student/onCampus/page.tsx index 27218304..29e8f459 100644 --- a/src/app/(routes)/student/onCampus/page.tsx +++ b/src/app/(routes)/student/onCampus/page.tsx @@ -27,7 +27,7 @@ const StudentPage = () => { return (
-

Offers

+

On Campus Offers

{onCampusOffers.length===0? (
diff --git a/src/components/jobs/OffCampusCard.tsx b/src/components/jobs/OffCampusCard.tsx index 79500b2b..ac600539 100644 --- a/src/components/jobs/OffCampusCard.tsx +++ b/src/components/jobs/OffCampusCard.tsx @@ -1,45 +1,17 @@ import React from "react"; -import Link from "next/link"; import { Separator } from "../ui/separator"; -import { fetchJobSalary } from "@/helpers/api"; -import { cookies } from "next/headers"; -import { useState, useEffect } from 'react'; -import {JobDetails} from "@/dummyData/jobdetails" -import { Button } from "@/components/ui/button"; -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" import { OffCampusOffer } from "@/helpers/student/types"; -import { GetSalaryById } from "@/helpers/student/api"; interface Props { jobItem: OffCampusOffer; } const OffCampusCard = ({ jobItem }: Props) => { - const [showDescription, setShowDescription] = useState(false); - - const handleViewDetails = () => { - setShowDescription(!showDescription); - }; - - const roundOff = (n: number) => { - return Math.round((n + Number.EPSILON) * 100) / 100; - }; - function formatNumber(num: number): string { if (num >= 1e7) { - // Convert to Crores const crores = num / 1e7; return `₹${crores.toFixed(2)} Crores`; } else if (num >= 1e5) { - // Convert to Lakhs const lakhs = num / 1e5; return `₹${lakhs.toFixed(2)} Lakhs`; } else { @@ -56,106 +28,34 @@ const OffCampusCard = ({ jobItem }: Props) => {
-
+
Role
{" "}
{jobItem.role}
+
+
Salary
{" "} +
{formatNumber(jobItem.salary)}
+
Period
{" "}
{jobItem.salaryPeriod}
-
Salary
{" "} -
{jobItem.salary}
+
Status
{" "} +
{jobItem.status}
Category
{" "}
{jobItem.company.category}
-
-
Type
{" "} -
{jobItem.season.type}
-
+
+
+ +
+
+ {jobItem.metadata}
- {showDescription && ( -
-
- -
-
-
-

About The Work

-
-
-
-
    -
  • - Build an application in Flutter and connect REST APIs to provide a - seamless experience to users -
  • -
  • - Take ownership of the application and work alongside backend and - database engineers to deliver tasks based on timeline -
  • -
  • Work with 3rd party services to integrate in app
  • -
  • - Attend daily standup calls to discuss team updates and next tasks -
  • -
-
- -
-

Skill(s) Required

-
-
- Algorithms -
-
- Android -
-
- Data Structures -
-
- Firebase -
-
- iOS -
-
- Flutter -
-
- REST API -
-
-
- -
-

Who can apply

-
    -
  • are available for the work from home job/internship
  • -
  • - can work from 8:00 pm - 2:00 am Indian Standard Time (as the company - is based outside of India & their local work timings are 9:30 am - - 3:30 pm Eastern Standard Time) -
  • -
  • - can start the work from home job/internship between 4th Jan24 and - 8th Feb24 -
  • -
  • are available for duration of 3 months
  • -
  • have relevant skills and interests
  • -
-
-
- -
-
- )}
); diff --git a/src/components/jobs/OnCampusCard.tsx b/src/components/jobs/OnCampusCard.tsx index 28717508..a0648b32 100644 --- a/src/components/jobs/OnCampusCard.tsx +++ b/src/components/jobs/OnCampusCard.tsx @@ -1,23 +1,8 @@ import React from "react"; -import Link from "next/link"; import { Separator } from "../ui/separator"; -import { fetchJobSalary } from "@/helpers/api"; import { useState, useEffect } from 'react'; -import {JobDetails} from "@/dummyData/jobdetails" -import { Button } from "@/components/ui/button"; -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectLabel, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" import { OnCampusOffers, Salary, Resume } from "@/helpers/student/types"; -import { ApplyJob, GetSalaryById } from "@/helpers/student/api"; -import Cookies from "js-cookie"; -import toast, { Toaster } from "react-hot-toast"; +import { GetSalaryById } from "@/helpers/student/api"; interface Props { jobItem: OnCampusOffers; salaryId: string; @@ -36,14 +21,6 @@ const OnCampusCard = ({ jobItem, salaryId }: Props) => { fetchSalary(); // setJobs(Jobs); }, [salaryId]); - const [showDescription, setShowDescription] = useState(false); - const handleViewDetails = () => { - setShowDescription(!showDescription); - }; - - const roundOff = (n: number) => { - return Math.round((n + Number.EPSILON) * 100) / 100; - }; function formatNumber(num: number): string { if (num >= 1e7) { @@ -69,15 +46,28 @@ const OnCampusCard = ({ jobItem, salaryId }: Props) => {
-
+
Role
{" "}
{jobItem.salary.job.role}
+
+
Status
{" "} +
{jobItem.status}
+
Period
{" "}
{salary.salaryPeriod}
+
+
Season
{" "} +
{jobItem.salary.job.season.type} {jobItem.salary.job.season.year}
+
+
+
+ +
+
CTC
{" "}
{formatNumber(salary.totalCTC)}
@@ -87,86 +77,18 @@ const OnCampusCard = ({ jobItem, salaryId }: Props) => {
{formatNumber(salary.baseSalary)}
-
Minimum CPI
{" "} -
{roundOff(salary.minCPI)}
+
Take Home Salary
{" "} +
{formatNumber(salary.takeHomeSalary)}
-
- {showDescription && ( -
-
- -
-
-
-

About The Work

-
- - View Details {'>'} - -
-
-
    -
  • - Build an application in Flutter and connect REST APIs to provide a - seamless experience to users -
  • -
  • - Take ownership of the application and work alongside backend and - database engineers to deliver tasks based on timeline -
  • -
  • Work with 3rd party services to integrate in app
  • -
  • - Attend daily standup calls to discuss team updates and next tasks -
  • -
-
- -
-

Skill(s) Required

-
-
- Algorithms -
-
- Android -
-
- Data Structures -
-
- Firebase -
-
- iOS -
-
- Flutter -
-
- REST API -
-
-
- -
-

Who can apply

-
    -
  • are available for the work from home job/internship
  • -
  • - can work from 8:00 pm - 2:00 am Indian Standard Time (as the company - is based outside of India & their local work timings are 9:30 am - - 3:30 pm Eastern Standard Time) -
  • -
  • - can start the work from home job/internship between 4th Jan24 and - 8th Feb24 -
  • -
  • are available for duration of 3 months
  • -
  • have relevant skills and interests
  • -
-
-
- )} +
+
Gross Salary
{" "} +
{formatNumber(salary.grossSalary)}
+
+
+
Other compensations
{" "} +
{formatNumber(salary.otherCompensations)}
+
+
)}
diff --git a/src/components/jobs/SalaryCard.tsx b/src/components/jobs/SalaryCard.tsx index 7096f1c5..f372232a 100644 --- a/src/components/jobs/SalaryCard.tsx +++ b/src/components/jobs/SalaryCard.tsx @@ -4,19 +4,16 @@ import { Table, TableHeader, TableBody, - TableFooter, TableHead, TableRow, TableCell, } from "@/components/ui/table"; -import { SampleJobData } from "@/dummyData/job"; import { Separator } from "@/components/ui/separator"; import { Resume, Salary } from "@/helpers/student/types"; import { ApplyJob, GetSalaryById } from "@/helpers/student/api"; import { Button } from "../ui/button"; -import Link from "next/link"; import Cookies from "js-cookie"; -import toast, { Toaster } from "react-hot-toast"; +import toast from "react-hot-toast"; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../ui/select"; interface Props{ @@ -57,21 +54,14 @@ export default function SalaryCard({salaryId, resumes}: Props) { setIsopen(!isopen); }; - const roundOff = (n: number) => { - return Math.round((n + Number.EPSILON) * 100) / 100; - }; - function formatNumber(num: number): string { if (num >= 1e7) { - // Convert to Crores const crores = num / 1e7; return `₹${crores.toFixed(2)} Crores`; } else if (num >= 1e5) { - // Convert to Lakhs const lakhs = num / 1e5; return `₹${lakhs.toFixed(2)} Lakhs`; } else if (num >= 1e3) { - // Convert to Lakhs const lakhs = num / 1e3; return `₹${lakhs.toFixed(2)}K`; } else { @@ -158,14 +148,31 @@ export default function SalaryCard({salaryId, resumes}: Props) { - {roundOff(salaryData?.minCPI)} - {roundOff(salaryData?.tenthMarks)} % - {roundOff(salaryData?.twelthMarks)} % + {salaryData?.minCPI.toFixed(2)} + {(salaryData?.tenthMarks*10).toFixed(2)} % + {(salaryData?.twelthMarks*10).toFixed(2)} %
+
+
Programs
+
+ {salaryData.programs?.length > 0 && ( + <> + {salaryData?.programs.map((g, i) => ( +
+ {g} +
+ ))} + + )} +
+
Gender
From 4716567410ae7e52bae594a48f014e6f3b56c69e Mon Sep 17 00:00:00 2001 From: AryanGKulkarni <95529889+AryanGKulkarni@users.noreply.github.com> Date: Sat, 15 Jun 2024 19:55:04 +0530 Subject: [PATCH 3/5] salary changes --- src/components/jobs/OnCampusCard.tsx | 3 +- src/components/jobs/SalaryCard.tsx | 246 +++++++++++++++------------ src/helpers/student/api.ts | 31 ++-- src/helpers/student/types.ts | 137 +++++++-------- 4 files changed, 227 insertions(+), 190 deletions(-) diff --git a/src/components/jobs/OnCampusCard.tsx b/src/components/jobs/OnCampusCard.tsx index a0648b32..47715297 100644 --- a/src/components/jobs/OnCampusCard.tsx +++ b/src/components/jobs/OnCampusCard.tsx @@ -3,6 +3,7 @@ import { Separator } from "../ui/separator"; import { useState, useEffect } from 'react'; import { OnCampusOffers, Salary, Resume } from "@/helpers/student/types"; import { GetSalaryById } from "@/helpers/student/api"; +import Cookies from "js-cookie"; interface Props { jobItem: OnCampusOffers; salaryId: string; @@ -13,7 +14,7 @@ const OnCampusCard = ({ jobItem, salaryId }: Props) => { useEffect(() => { const fetchSalary = async () => { - const data = await GetSalaryById(salaryId); + const data = await GetSalaryById(salaryId, Cookies.get("accessToken")); setSalary(data); console.log(data); }; diff --git a/src/components/jobs/SalaryCard.tsx b/src/components/jobs/SalaryCard.tsx index f372232a..0b105466 100644 --- a/src/components/jobs/SalaryCard.tsx +++ b/src/components/jobs/SalaryCard.tsx @@ -15,6 +15,12 @@ import { Button } from "../ui/button"; import Cookies from "js-cookie"; import toast from "react-hot-toast"; import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from "../ui/select"; +import Link from "next/link"; +const baseUrl = process.env.NEXT_PUBLIC_BACKEND_URL; + +const url = (NextUrl: string) => { + return `${baseUrl}/api/v1${NextUrl}`; +}; interface Props{ salaryId: string; @@ -24,14 +30,17 @@ interface Props{ export default function SalaryCard({salaryId, resumes}: Props) { const [salaryData, setSalaryData] = useState(null); + const fetchSalaryData = async () => { + const data = await GetSalaryById(salaryId, Cookies.get("accessToken")); + setSalaryData(data); + console.log("salary ",data) + }; + useEffect(() => { - const fetchSalaryData = async () => { - const data = await GetSalaryById(salaryId); - setSalaryData(data); - }; - - fetchSalaryData(); - }, [salaryId]); + if(salaryData===null){ + fetchSalaryData(); + } + }); const [selectedResume, setSelectedResume] = useState(null); @@ -43,6 +52,7 @@ export default function SalaryCard({salaryId, resumes}: Props) { const data = await ApplyJob(Cookies.get("accessToken"),salaryId,selectedResume); if(data.status===201){ toast.success("Applied Successfully"); + fetchSalaryData(); } else{ toast.error("Cannot Apply"); @@ -55,6 +65,7 @@ export default function SalaryCard({salaryId, resumes}: Props) { }; function formatNumber(num: number): string { + console.log(num); if (num >= 1e7) { const crores = num / 1e7; return `₹${crores.toFixed(2)} Crores`; @@ -71,29 +82,34 @@ export default function SalaryCard({salaryId, resumes}: Props) { return (
- {salaryData===null? ( + {salaryData===null || salaryData==undefined? (
No Data
): (
-
- {salaryData?.job.company.name} -
-
- CTC Offered: {formatNumber(salaryData?.totalCTC)} -
+
+
+ {salaryData?.job.company.name} + {salaryData.job.applications.length > 0 && ( + <> +
+ {"Applied"} +
+ + )}
+
+
+ CTC Offered: {formatNumber(salaryData?.totalCTC)} +
+
@@ -105,10 +121,6 @@ export default function SalaryCard({salaryId, resumes}: Props) {
Base Salary
{formatNumber(salaryData?.baseSalary)}
-
-
CTC
{" "} -
{formatNumber(salaryData?.totalCTC)}
-
Take Home Salary @@ -126,119 +138,131 @@ export default function SalaryCard({salaryId, resumes}: Props) {
{formatNumber(salaryData?.otherCompensations)}
-
Period
{" "} -
Annual
+
Duration
{" "} +
{salaryData.salaryPeriod}
{isopen && ( <> -
+
+ +
+
+
+
+
Selection mode
{" "} +
{salaryData.job.selectionProcedure.selectionMode}
+
+
+
Shortlist from Resume
{" "} +
{salaryData.job.selectionProcedure.shortlistFromResume? "YES":"NO"}
+
+
+
Group Discussion
{" "} +
{salaryData.job.selectionProcedure.groupDiscussion? "YES":"NO"}
+
+
- +
-
Criteria
+
Selection Procedure
+

Tests

- Minimum CPI - Class X Percentage - Class XII Percentage + Sr. + Type + Duration - - {salaryData?.minCPI.toFixed(2)} - {(salaryData?.tenthMarks*10).toFixed(2)} % - {(salaryData?.twelthMarks*10).toFixed(2)} % - + {salaryData.job.selectionProcedure.tests.map((test, index) => ( + + {index+1} + {test.type} + {test.duration} + + ))}
-
- -
-
Programs
-
- {salaryData.programs?.length > 0 && ( - <> - {salaryData?.programs.map((g, i) => ( -
- {g} -
- ))} - - )} -
-
-
-
Gender
-
- {salaryData.genders?.length > 0 && ( - <> - {salaryData?.genders.map((g, i) => ( -
- {g} -
- ))} - - )} -
-
- -
-
Categories
-
- {salaryData.categories?.length > 0 && ( - <> - {salaryData?.categories.map((c, i) => ( -
- {c} -
- ))} - - )} -
-
- -
-
- Faculty Approval Requests -
+

Interviews

- Name - Department - E-mail - Contact - Status - Remarks + Sr. + Type + Duration - - {salaryData?.facultyApprovalRequests.map((g, i) => ( - - {g.faculty.user.name} - {g.faculty.department} - {g.faculty.user.email} - {g.faculty.user.contact} - {g.status} - {g.remarks} - + {salaryData.job.selectionProcedure.interviews.map((test, index) => ( + + {index+1} + {test.type} + {test.duration} + ))}
+
+ +
+ +
Events
+ + + + Round + Type + Date + + + + {salaryData.job.events.map((event, index) => ( + + {event.roundNumber} + {event.type} + {event.startDateTime} + + ))} + +
+ + {salaryData.job.applications.length > 0 && ( + <> +
+ +
+ +
Applications
+ + + + Sr. + Resume + Status + + + + {salaryData.job.applications.map((application, index) => ( + + {index+1} + + + {application.resume.filepath} + + + {application.resume.verified? "Verified": "Not Verified"} + + ))} + +
+ + )} + +
diff --git a/src/app/(routes)/student/resumes/page.tsx b/src/app/(routes)/student/resumes/page.tsx index 1293e386..69be55c2 100644 --- a/src/app/(routes)/student/resumes/page.tsx +++ b/src/app/(routes)/student/resumes/page.tsx @@ -18,6 +18,7 @@ import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { uploadResume } from "@/helpers/student/api"; import toast, { Toaster } from "react-hot-toast"; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; const baseUrl = process.env.NEXT_PUBLIC_BACKEND_URL; @@ -31,17 +32,13 @@ const url = (NextUrl: string) => { const ResumePage = () => { const [resumeData, setResumeData] = useState([]); - const [showUploadForm, setShowUploadForm] = useState(false); + const [dialogOpen, setDialogOpen] = useState(false); const fetchResumes = async () => { const data = await GetResumes(Cookies.get("accessToken")); setResumeData(data); } - const handleUploadForm = () => { - setShowUploadForm(true); - } - const [file, setFile] = useState(null); const handleFileChange = (event: ChangeEvent) => { @@ -67,6 +64,7 @@ const ResumePage = () => { toast.success("Uploaded Successfully"); fetchResumes(); setFile(null); + setDialogOpen(false) } else{ toast.error("Error uploading file") @@ -136,19 +134,45 @@ const ResumePage = () => {
- + + + + + + + Upload Resume + + Select and upload your resume file. + + +
+
+ + +
+
+ + +
+ + + +
+
+
- {showUploadForm && ( -
-
-
- - -
- -
-
- )} ); }; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 6670d4a6..d549816f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -15,7 +15,7 @@ import { Suspense } from "react"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { - title: "Create Next App", + title: "TPC Portal", description: "Generated by create next app", }; diff --git a/src/components/SideBar/Roles/student.tsx b/src/components/SideBar/Roles/student.tsx index 9da4d50f..c717ab7d 100644 --- a/src/components/SideBar/Roles/student.tsx +++ b/src/components/SideBar/Roles/student.tsx @@ -119,6 +119,41 @@ const StudentDashboard = () => { {/* */}
+ +
+
+
+ + + +
+ + Jobs + +
+ + {/* */} +
+
diff --git a/src/components/loginForms/loginForm.tsx b/src/components/loginForms/loginForm.tsx index 9f9d4b20..876d9ebe 100644 --- a/src/components/loginForms/loginForm.tsx +++ b/src/components/loginForms/loginForm.tsx @@ -9,7 +9,7 @@ import Cookies from "js-cookie"; import { jwtDecode } from "jwt-decode"; const LoginForm = () => { const [email, setemail] = useState(null); - const [role, setrole] = useState(null); + const [role, setrole] = useState("STUDENT"); const router = useRouter(); return ( <> diff --git a/yarn.lock b/yarn.lock index f1887c36..ae7b1a4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4696,16 +4696,7 @@ string-convert@^0.2.0: resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4769,14 +4760,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==