Skip to content

Commit

Permalink
Merge branch 'faculty-view' of https://github.com/Princekumarofficial…
Browse files Browse the repository at this point in the history
…/tpc-frontend into faculty-view
  • Loading branch information
Princekumarofficial committed Jun 13, 2024
2 parents 7702cc7 + 28bc436 commit da35864
Show file tree
Hide file tree
Showing 47 changed files with 6,854 additions and 2,056 deletions.
441 changes: 334 additions & 107 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
},
"dependencies": {
"@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",
Expand All @@ -30,25 +32,30 @@
"clsx": "^2.0.0",
"cmdk": "^0.2.0",
"csv-parser": "^3.0.0",
"dayjs": "^1.11.10",
"embla-carousel-react": "^8.0.0-rc19",
"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",
"next": "latest",
"material-icons": "^1.13.12",
"next": "^14.1.4",
"next-auth": "^4.23.2",
"papaparse": "^5.4.1",
"pdf-lib": "^1.17.1",
"prettier": "^3.1.1",
"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-onclickoutside": "^6.13.1",
"react-redux": "^9.0.4",
"react-responsive": "^10.0.0",
"react-table": "^7.8.0",
Expand All @@ -59,6 +66,7 @@
"yup": "^1.3.3"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.7",
"@types/js-cookie": "^3.0.6",
"@types/node": "latest",
"@types/papaparse": "^5.3.10",
Expand Down
21 changes: 0 additions & 21 deletions src/app/(routes)/student/[studentId]/page.tsx

This file was deleted.

87 changes: 87 additions & 0 deletions src/app/(routes)/student/interviewExperiences/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"use client";
import React, { useState } from "react";
import { Separator } from "../../../../components/ui/separator";
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent,
} from '@radix-ui/react-accordion';
import { ChevronDownIcon } from '@radix-ui/react-icons';
import {interviewExpData} from "../../../../dummyData/Interviews";

// interface Props {
// interviewExpData: InterviewExperience[];
// }



interface InterviewExperience {
ques: string;
ans: string;
student_name: string;
difficulty:string,
tags:Array<string>;
}

const InterviewExperiencesPage = () => {
const [open, setOpen] = useState<boolean>(false);
return (
<div>
<div>
<h1 className="text-xl font-bold px-3 py-5">Interview Experiences</h1>
</div>
<Separator/>
<div>
<Accordion
className=""
type="single"
defaultValue="1"
collapsible

>
{interviewExpData.map((e,i)=>(

<AccordionItem key={i} value={String(i+1)}
className="py-6 px-4 bg-white my-3 rounded-xl hover:drop-shadow-[0_0px_10px_rgba(0,0,0,0.25)] ">
<AccordionTrigger
className="font-semibold px-1 flex"
>
{e.ques}
<ChevronDownIcon className="ml-3 mt-0.5"/>


</AccordionTrigger>

<AccordionContent
className="px-1 pt-4"
>
<Separator className="mb-3"/>
{e.ans}
<br/>
<div className="flex gap-3">
<div className=" bg-slate-400 text-white mt-3 font-semibold px-2 py-1 border rounded-3xl inline-block text-xs ">
By {e.student_name}
</div>
<div className=" text-slate-500 mt-3 font-semibold px-2 py-1 border rounded-3xl inline-block border-slate-500 text-xs ">
{e.difficulty}
</div>
<div className=" text-slate-500 mt-3 font-semibold px-2 py-1 border rounded-3xl inline-block border-slate-500 text-xs ">
{e.tags[0]}
</div>
<div className=" text-slate-500 mt-3 font-semibold px-2 py-1 border rounded-3xl inline-block border-slate-500 text-xs ">
{e.tags[1]}
</div>
</div>
</AccordionContent>
</AccordionItem>

))}
</Accordion>
</div>

</div>
)
}

export default InterviewExperiencesPage;
228 changes: 228 additions & 0 deletions src/app/(routes)/student/jobs/[jobId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
"use client";
import React, { useEffect, useState } from "react";
import { Separator } from "@/components/ui/separator";
import Link from "next/link";
import {
Table,
TableHeader,
TableBody,
TableFooter,
TableHead,
TableRow,
TableCell,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { fetchEachJob } from "@/helpers/api";
import HorizontalTimeline from "@/components/HorizontalTimeline";
import { Job, CustomEvent, EventData, CalenderEvent } from "@/helpers/student/types";
import { GetJobById } from "@/helpers/student/api";

function transformEvents(events: CustomEvent[]): EventData[] {

// Get the current date
const currentDate = new Date();

// Sort events by startDateTime
const sortedEvents = events.sort((a, b) => new Date(a.startDateTime).getTime() - new Date(b.startDateTime).getTime());

// Transform the sorted events into the desired format
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'), // Convert date to DD/MM/YYYY format
status,
title: event.type,
};
});

// Find the first event after the current date and mark it as 'selected'
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) {
// If all events have passed, mark the last event as 'selected'
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), // startDate at midnight
description: event.metadata,
id: event.id,
label: "red", // assuming a fixed label as the original data doesn't provide this
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();
}

const faculty = [
{ name: 'Emily Johnson', designation: 'Professor', email: '[email protected]', phoneNumber: '123-456-7890' },
{ name: 'Alex Smith', designation: 'Assistant Professor', email: '[email protected]', phoneNumber: '987-654-3210' },
];

const JobPage = ({ params }: { params: { jobId: string } }) => {

const [jobData, setJobData] = useState<Job | null>(null);

useEffect(() => {
const fetchJobData = async () => {
const data = await GetJobById(params.jobId);
setJobData(data);
storeCalenderEvents(data);
};

fetchJobData();

}, [params.jobId]);


return (
<div className="m-10 bg-white p-5 border-2 rounded-xl">
{jobData===null? (
<div>No Data</div>
): (
<>
<div className="font-semibold text-xl">{jobData?.companyDetailsFilled.name}</div>
<div className="text-gray-600 font-medium text-sm my-1">
{jobData?.companyDetailsFilled.address.city}, {jobData?.companyDetailsFilled.address.state}, {jobData?.companyDetailsFilled.address.country}
</div>
<div className="my-4">
<Separator />
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-5 text-sm mx-2">
<div>
<div className="text-gray-500 font-semibold my-2">Website</div>{" "}
<a className="text-blue-500" href={jobData.companyDetailsFilled.website} target="_blank" rel="noopener noreferrer">Link</a>
</div>
<div>
<div className="text-gray-500 font-semibold my-2">Domain</div>{" "}
<div>
{jobData?.companyDetailsFilled.domains.length === 0
? "Not Available"
: jobData?.companyDetailsFilled.domains[0]}
</div>
</div>
<div>
<div className="text-gray-500 font-semibold my-2">Category</div>{" "}
<div>{jobData?.companyDetailsFilled.category}</div>
</div>
<div>
<div className="text-gray-500 font-semibold my-2">Company Size</div>{" "}
<div>{formatNumber(jobData?.companyDetailsFilled.size ?? 0)}</div>
</div>
<div>
<div className="text-gray-500 font-semibold my-2">Established</div>{" "}
<div>{jobData?.companyDetailsFilled.yearOfEstablishment}</div>
</div>
</div>
<div className="my-4">
<Separator />
</div>
<h1 className="text-lg font-semibold my-2">Recruiter</h1>
<Table className="overflow-hidden">
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Designation</TableHead>
<TableHead>Email</TableHead>
<TableHead>Mobile Number</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>{jobData?.recruiterDetailsFilled.name}</TableCell>
<TableCell>{jobData?.recruiterDetailsFilled.designation}</TableCell>
<TableCell>{jobData?.recruiterDetailsFilled.email}</TableCell>
<TableCell>{jobData?.recruiterDetailsFilled.contact}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
</TableFooter>
</Table>
<div className="my-4">
<Separator />
</div>
<h1 className="text-lg font-semibold my-2">Job Coordinators</h1>
<Table className="overflow-hidden">
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Role</TableHead>
<TableHead>Department</TableHead>
<TableHead>Email</TableHead>
<TableHead>Mobile Number</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{jobData?.jobCoordinators.map((coordinator, index) => (
<TableRow key={index}>
<TableCell>{coordinator.tpcMember.user.name}</TableCell>
<TableCell>{coordinator.role}</TableCell>
<TableCell>{coordinator.tpcMember.department}</TableCell>
<TableCell>{coordinator.tpcMember.user.email}</TableCell>
<TableCell>{coordinator.tpcMember.user.contact}</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
</TableFooter>
</Table>
<div className="my-4">
<Separator />
</div>
<HorizontalTimeline eventsData={transformEvents(jobData.events)} />
{/* <HorizontalTimeline eventsData={testData} /> */}
<div className="my-7">
<Separator />
</div>
<div>
<div className="flex justify-between">
<div>
<Button>
<a href={`/student/jobs/salary/${params.jobId}`} target="_blank" rel="noopener noreferrer">Salary</a>
</Button>
</div>
<div>
<Button>
<a href={"/events"} target="_blank" rel="noopener noreferrer">Events</a>
</Button>
</div>
</div>
</div>
</>
)}
</div>
);
};

export default JobPage;
Loading

0 comments on commit da35864

Please sign in to comment.